diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b0ba033549db..20aaf9dbe632 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -100,6 +100,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-7040-db-nand.dtb \ armada-8040-db.dtb \ armada-8040-mcbin.dtb \ + armada-8040-cex.dtb \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ @@ -456,7 +457,8 @@ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb dtb-$(CONFIG_ARCH_IMX8) += fsl-imx8qxp-mek.dtb -dtb-$(CONFIG_ARCH_IMX8M) += fsl-imx8mq-evk.dtb +dtb-$(CONFIG_ARCH_IMX8M) += fsl-imx8mq-evk.dtb \ + fsl-imx8mq-hb.dtb dtb-$(CONFIG_RCAR_GEN3) += \ r8a7795-h3ulcb-u-boot.dtb \ diff --git a/arch/arm/dts/armada-8040-cex.dts b/arch/arm/dts/armada-8040-cex.dts new file mode 100644 index 000000000000..0c1cf94bb86e --- /dev/null +++ b/arch/arm/dts/armada-8040-cex.dts @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 SolidRun International Ltd. + */ + +#include "armada-8040.dtsi" /* include SoC device tree */ + +/ { + model = "Armada-8040-cex"; + compatible = "marvell,armada-8040-cex", + "marvell,armada8040"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + i2c0 = &cpm_i2c0; + i2c1 = &cpm_i2c1; + i2c2 = &cps_i2c1; + spi0 = &cps_spi1; + gpio0 = &ap_gpio0; + gpio1 = &cpm_gpio0; + gpio2 = &cpm_gpio1; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + simple-bus { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + reg_usb3h0_vbus: usb3-vbus0 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_xhci_vbus_pins>; + regulator-name = "reg-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <500000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&cpm_gpio1 15 GPIO_ACTIVE_HIGH>; /* GPIO[47] */ + }; + }; +}; + +/* Accessible over the mini-USB CON9 connector on the main board */ +&uart0 { + status = "okay"; +}; + +&ap_pinctl { + /* + * MPP Bus: + * eMMC [0-10] + * UART0 [11,19] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 1 1 1 1 1 1 1 1 1 1 + 1 3 0 0 0 0 0 0 0 3 >; +}; + +/* on-board eMMC */ +&ap_sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&ap_emmc_pins>; + bus-width= <8>; + status = "okay"; +}; + +&cpm_pinctl { + /* + * MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins: + * [11] CLKOUT_MPP_11 (out) + * [23] LINK_RD_IN_CP2CP (in) + * [25] CLKOUT_MPP_25 (out) + * [29] AVS_FB_IN_CP2CP (in) + * [32,34] SMI + * [33] MSS power down + * [35-38] CP0 I2C1 and I2C0 + * [39] MSS CKE Enable + * [40,41] CP0 UART1 TX/RX + * [42,43] XSMI (controls two 10G phys) + * [47] USB VBUS EN + * [48] FAN PWM + * [49] 10G port 1 interrupt + * [50] 10G port 0 interrupt + * [51] 2.5G SFP TX fault + * [52] PCIe reset out + * [53] 2.5G SFP mode + * [54] 2.5G SFP LOS + * [55] Micro SD card detect + * [56-61] Micro SD + * [62] CP1 SFI SFP FAULT + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 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 0 7 0xa 7 2 2 2 2 0xa + 7 7 8 8 0 0 0 0 0 0 + 0 0 0 0 0 0 0xe 0xe 0xe 0xe + 0xe 0xe 0 >; + + cpm_xhci_vbus_pins: cpm-xhci-vbus-pins { + marvell,pins = < 47 >; + marvell,function = <0>; + }; + + cpm_pcie_reset_pins: cpm-pcie-reset-pins { + marvell,pins = < 52 >; + marvell,function = <0>; + }; +}; + +/* uSD slot */ +&cpm_sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sdhci_pins>; + bus-width= <4>; + status = "okay"; +}; + +/* PCIe x4 */ +&cpm_pcie0 { + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_pcie_reset_pins>; + marvell,reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_HIGH>; /* GPIO[52] */ + status = "okay"; +}; + +&cpm_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; +}; + +&cpm_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c1_pins>; + status = "okay"; + clock-frequency = <100000>; +}; + +&cpm_sata0 { + status = "okay"; +}; + +&cpm_comphy { + /* + * CP0 Serdes Configuration: + * Lane 0: PCIe0 (x4) + * Lane 1: PCIe0 (x4) + * Lane 2: PCIe0 (x4) + * Lane 3: PCIe0 (x4) + * Lane 4: SFI (10G) + * Lane 5: SATA1 + */ + phy0 { + phy-type = ; + }; + phy1 { + phy-type = ; + }; + phy2 { + phy-type = ; + }; + phy3 { + phy-type = ; + }; + phy4 { + phy-type = ; + }; + phy5 { + phy-type = ; + }; +}; + +&cps_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_i2c1_pins>; + status = "okay"; + clock-frequency = <100000>; +}; + +&cps_sata0 { + status = "okay"; +}; + +&cps_usb3_0 { + vbus-supply = <®_usb3h0_vbus>; + status = "okay"; +}; + +&cps_utmi0 { + status = "okay"; +}; + +&cps_pinctl { + /* + * MPP Bus: + * [0-5] TDM + * [6,7] CP1_UART 0 + * [8] CP1 10G SFP LOS + * [9] CP1 10G PHY RESET + * [10] CP1 10G SFP TX Disable + * [11] CP1 10G SFP Mode + * [12] SPI1 CS1n + * [13] SPI1 MISO (TDM and SPI ROM shared) + * [14] SPI1 CS0n + * [15] SPI1 MOSI (TDM and SPI ROM shared) + * [16] SPI1 CLK (TDM and SPI ROM shared) + * [24] CP1 2.5G SFP TX Disable + * [26] CP0 10G SFP TX Fault + * [27] CP0 10G SFP Mode + * [28] CP0 10G SFP LOS + * [29] CP0 10G SFP TX Disable + * [30] USB Over current indication + * [31] 10G Port 0 phy reset + * [32-62] = 0xff: Keep default CP1_shared_pins: + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0x4 0x4 0x4 0x4 0x4 0x4 0x8 0x8 0x0 0x0 + 0x0 0x0 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0x0 0xff 0x0 0x0 0x0 0x0 + 0x0 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>; +}; + +&cps_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_spi1_pins>; + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@400000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; +}; + +&cps_comphy { + /* + * CP1 Serdes Configuration: + * Lane 0: mPCIe0 (x1) + * Lane 1: SATA 0 + * Lane 2: USB HOST 0 + * Lane 3: SGMII1 + * Lane 4: SFI (10G) + * Lane 5: mPCIe1 (x1) + */ + phy0 { + phy-type = ; + }; + phy1 { + phy-type = ; + }; + phy2 { + phy-type = ; + }; + phy3 { + phy-type = ; + phy-speed = ; + }; + phy4 { + phy-type = ; + }; + phy5 { + phy-type = ; + }; +}; diff --git a/arch/arm/dts/fsl-imx8mq-hb.dts b/arch/arm/dts/fsl-imx8mq-hb.dts new file mode 100644 index 000000000000..7766f7523e11 --- /dev/null +++ b/arch/arm/dts/fsl-imx8mq-hb.dts @@ -0,0 +1,439 @@ +/* + * 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/; + +/* First 128KB is for PSCI ATF. */ +/memreserve/ 0x40000000 0x00020000; + +#include "fsl-imx8mq.dtsi" + +/ { + model = "SolidRun i.MX8MQ HummingBoard Pulse"; + compatible = "solidrun,hummingboard-pulse", "fsl,imx8mq"; + + chosen { + bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,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; + }; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + + imx8mq-sr-hb { + 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_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_uart2: uart2grp { + fsl,pins = < + MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49 + MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x79 + MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x79 + MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x79 + MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x79 + 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 0x85 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87 + 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 0x85 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + 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_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 = <ðphy0>; + 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 = "disabled"; +}; + +&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>; + }; +}; + +&uart1 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + assigned-clocks = <&clk IMX8MQ_CLK_UART1_SRC>; + assigned-clock-parents = <&clk IMX8MQ_CLK_25M>; + status = "okay"; +}; + +&uart2 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + assigned-clocks = <&clk IMX8MQ_CLK_UART2_SRC>; + 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 = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usb3_0 { + status = "okay"; +}; + +&usb_dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usb3_1 { + status = "okay"; +}; + +&usb_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; diff --git a/arch/arm/dts/fsl-imx8mq.dtsi b/arch/arm/dts/fsl-imx8mq.dtsi index 814a1b7df4cf..0857c9f95ff5 100644 --- a/arch/arm/dts/fsl-imx8mq.dtsi +++ b/arch/arm/dts/fsl-imx8mq.dtsi @@ -29,6 +29,10 @@ aliases { ethernet0 = &fec1; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; mmc0 = &usdhc1; mmc1 = &usdhc2; gpio0 = &gpio1; @@ -278,6 +282,139 @@ interrupt-parent = <&gic>; }; + uart1: serial@30860000 { + compatible = "fsl,imx8mq-uart", "fsl,imx6ul-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; + reg = <0x0 0x30860000 0x0 0x10000>; + interrupts = ; + clocks = <&clk IMX8MQ_CLK_UART1_ROOT>, + <&clk IMX8MQ_CLK_UART1_ROOT>; + clock-names = "ipg", "per"; + interrupt-parent = <&gpc>; + status = "disabled"; + }; + + uart3: serial@30880000 { + compatible = "fsl,imx8mq-uart", "fsl,imx6ul-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; + reg = <0x0 0x30880000 0x0 0x10000>; + interrupts = ; + 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,imx6ul-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; + reg = <0x0 0x30890000 0x0 0x10000>; + interrupts = ; + 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"; + }; + + uart4: serial@30a60000 { + compatible = "fsl,imx8mq-uart", "fsl,imx6ul-uart", + "fsl,imx6q-uart", "fsl,imx21-uart"; + reg = <0x0 0x30a60000 0x0 0x10000>; + interrupts = ; + 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"; + }; + + 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_SRC>; + 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_SRC>, + <&clk IMX8MQ_CLK_USB_CORE_REF_SRC>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, + <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <500000000>, <100000000>; + reg = <0x0 0x38100000 0x0 0x10000>; + status = "disabled"; + + usb_dwc3_0: dwc3 { + compatible = "snps,dwc3"; + reg = <0x0 0x38100000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gpc>; + phys = <&usb3_phy0 0>, <&usb3_phy0 1>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&power 2>; + snps,power-down-scale = <2>; + snps,dis_u2_susphy_quirk; + 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_SRC>; + 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_SRC>, + <&clk IMX8MQ_CLK_USB_CORE_REF_SRC>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, + <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <500000000>, <100000000>; + reg = <0x0 0x38200000 0x0 0x10000>; + status = "disabled"; + + usb_dwc3_1: dwc3 { + compatible = "snps,dwc3"; + reg = <0x0 0x38200000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gpc>; + phys = <&usb3_phy1 0>, <&usb3_phy1 1>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&power 3>; + snps,power-down-scale = <2>; + snps,dis_u2_susphy_quirk; + status = "disabled"; + }; + }; + usdhc1: usdhc@30b40000 { compatible = "fsl,imx8mq-usdhc", "fsl,imx7d-usdhc"; reg = <0x0 0x30b40000 0x0 0x10000>; @@ -308,6 +445,30 @@ status = "disabled"; }; + sdma1: sdma@30bd0000 { + compatible = "fsl,imx8mq-sdma", "fsl,imx7d-sdma"; + reg = <0x0 0x30bd0000 0x0 0x10000>; + interrupts = ; + 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 = ; + 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"; + status = "okay"; + }; + fec1: ethernet@30be0000 { compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec"; reg = <0x0 0x30be0000 0x0 0x10000>; diff --git a/arch/arm/include/asm/arch-imx8m/sys_proto.h b/arch/arm/include/asm/arch-imx8m/sys_proto.h index d328542ece21..069dc3579621 100644 --- a/arch/arm/include/asm/arch-imx8m/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8m/sys_proto.h @@ -11,6 +11,8 @@ void set_wdog_reset(struct wdog_regs *wdog); void enable_tzc380(void); void restore_boot_params(void); +int imx8m_usb_power(int usb_id, bool on); +int imx8m_gpc_power(int id, bool on); extern unsigned long rom_pointer[]; enum boot_device get_boot_device(void); bool is_usb_boot(void); diff --git a/arch/arm/include/asm/arch-mx5/sys_proto.h b/arch/arm/include/asm/arch-mx5/sys_proto.h index c8aff2b65dc9..e94b7da99193 100644 --- a/arch/arm/include/asm/arch-mx5/sys_proto.h +++ b/arch/arm/include/asm/arch-mx5/sys_proto.h @@ -8,4 +8,5 @@ #include +bool is_usb_boot(void); #endif /* __SYS_PROTO_IMX5_ */ diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h index 4174f244afa1..13d85385136d 100644 --- a/arch/arm/include/asm/arch-mx6/crm_regs.h +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h @@ -6,6 +6,7 @@ #ifndef __ARCH_ARM_MACH_MX6_CCM_REGS_H__ #define __ARCH_ARM_MACH_MX6_CCM_REGS_H__ +#define CCM_CBCMR 0x020c4018 #define CCM_CCOSR 0x020c4060 #define CCM_CCGR0 0x020C4068 #define CCM_CCGR1 0x020C406c @@ -14,7 +15,9 @@ #define CCM_CCGR4 0x020C4078 #define CCM_CCGR5 0x020C407c #define CCM_CCGR6 0x020C4080 +#define CCM_CCGR7 0x020C4084 +#define CCM_ANALOG_PFD_528 0x020c8100 #define PMU_MISC2 0x020C8170 #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 4bf7dff8b4d0..a38841605863 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -30,4 +30,5 @@ static inline void iomuxc_set_rgmii_io_voltage(int io_vol) __raw_writel(io_vol, IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE_RGMII); } +bool is_usb_boot(void); #endif /* __SYS_PROTO_IMX6_ */ diff --git a/arch/arm/include/asm/arch-mx7/sys_proto.h b/arch/arm/include/asm/arch-mx7/sys_proto.h index e46a02198d66..42663a438879 100644 --- a/arch/arm/include/asm/arch-mx7/sys_proto.h +++ b/arch/arm/include/asm/arch-mx7/sys_proto.h @@ -9,5 +9,6 @@ void set_wdog_reset(struct wdog_regs *wdog); enum boot_device get_boot_device(void); +bool is_usb_boot(void); #endif /* __SYS_PROTO_IMX7_ */ diff --git a/arch/arm/include/asm/arch-mx8m/video_common.h b/arch/arm/include/asm/arch-mx8m/video_common.h new file mode 100644 index 000000000000..cdeec6999ce1 --- /dev/null +++ b/arch/arm/include/asm/arch-mx8m/video_common.h @@ -0,0 +1,40 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#ifndef __ASM_ARCH_VIDEO_COMMON_H__ +#define __ASM_ARCH_VIDEO_COMMON_H__ +#include +#include + +struct video_mode_settings { + uint32_t pixelclock; /* horizontal resolution */ + uint16_t xres; /* horizontal resolution */ + uint16_t yres; /* vertical resolution */ + uint16_t hfp; /* horizontal front porch */ + uint16_t hbp; /* horizontal back porch */ + uint16_t vfp; /* vertical front porch */ + uint16_t vbp; /* vertical back porch */ + uint16_t hsync; /* horizontal sync pulse width */ + uint16_t vsync; /* vertical sync pulse width */ + bool hpol; /* horizontal pulse polarity */ + bool vpol; /* vertical pulse polarity */ +}; + +#define PS2KHZ(ps) (1000000000UL / (ps)) +struct video_mode_settings *imx8m_get_gmode(void); +GraphicDevice *imx8m_get_gd(void); +void imx8m_show_gmode(void); +void imx8m_create_color_bar( + void *start_address, + struct video_mode_settings *vms); +int imx8m_fb_init( + struct fb_videomode const *mode, + uint8_t disp, + uint32_t pixfmt); +void imx8m_fb_disable(void); + +#endif /* __ASM_ARCH_VIDEO_COMMON_H__ */ diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 8d6832a33104..4f088ec185ac 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -133,5 +133,6 @@ int mxs_wait_mask_set(struct mxs_register_32 *reg, u32 mask, u32 timeout); int mxs_wait_mask_clr(struct mxs_register_32 *reg, u32 mask, u32 timeout); unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2); + unsigned long reg1, unsigned long reg2, + unsigned long reg3); #endif diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index e5f7267be193..0b6092e2ec41 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -78,6 +78,7 @@ ENDPROC(relocate_vectors) */ ENTRY(relocate_code) + stmdb sp!, {lr} ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ subs r4, r0, r1 /* r4 <- relocation offset */ beq relocate_done /* skip relocation */ @@ -100,6 +101,20 @@ fixloop: cmp r1, #R_ARM_RELATIVE bne fixnext + tst r0, #3 + beq 1f + sub r0, r2, #8 + bl prhex + mov r0, #':' + bl pr_c + ldr r0,[r2, #-8] + bl prhex + mov r0, #'_' + bl pr_c + ldr r0,[r2, #-4] + bl prhex + b fixnext +1: /* relative fix: increase location by offset */ add r0, r0, r4 ldr r1, [r0] @@ -125,7 +140,81 @@ relocate_done: #ifdef __ARM_ARCH_4__ mov pc, lr #else - bx lr + ldmia sp!, {pc} #endif ENDPROC(relocate_code) + +ENTRY(prhex) + stmdb sp!, {r0-r6,lr} + mov r6, #8 + mov r5, r0 +1: mov r0, r5, lsr #28 + cmp r0, #10 + addlt r0, r0, #'0' + addge r0, r0, #'a' - 10 + bl pr_c + mov r5, r5, lsl #4 + subs r6, r6, #1 + bne 1b + + mov r0,#'\n' + bl pr_c + mov r0,#'\r' + bl pr_c + ldmia sp!, {r0-r6,pc} +ENDPROC(prhex) + +#define UTXD 0x40 +#define UTS 0xb4 +#define UTS_TXEMPTY (1<<6) + +ENTRY(pr_c) + stmdb sp!, {r0-r1,lr} + ldr r1, =CONFIG_MXC_UART_BASE + str r0, [r1,#UTXD] + +1: ldr r0, [r1,#UTS] + tst r0, #UTS_TXEMPTY + beq 1b + ldmia sp!, {r0-r1,pc} +ENDPROC(pr_c) + +#if 0 +ENTRY(verify_relocate_table) + stmdb sp!, {lr} + /* + * check .rel.dyn relocations + */ + ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ + ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */ +1: + ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ + and r1, r1, #0xff + cmp r1, #R_ARM_RELATIVE + bne 3f + + tst r0, #3 + beq 2f + sub r0, r2, #8 + bl prhex + mov r0, #':' + bl pr_c + ldr r0,[r2, #-8] + bl prhex + mov r0, #'_' + bl pr_c + ldr r0,[r2, #-4] + bl prhex + mov r0, #1 + ldmia sp!, {pc} +2: +3: + cmp r2, r3 + blo 1b + + mov r0, #0 + ldmia sp!, {pc} + +ENDPROC(verify_relocate_table) +#endif diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index d236e4051083..2d501d5145d6 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -16,6 +16,7 @@ endif obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o obj-$(CONFIG_FEC_MXC) += mac.o obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o +obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o obj-y += cpu.o endif diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 80d9ff48a439..eeea0156d36c 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -15,6 +15,9 @@ #include #include #include +#if defined(CONFIG_VIDEO_IMXDCSS) +#include +#endif #include #include #include @@ -298,6 +301,9 @@ void arch_preboot_os(void) #if defined(CONFIG_VIDEO_MXS) lcdif_power_down(); #endif +#if defined(CONFIG_VIDEO_IMXDCSS) + imx8m_fb_disable(); +#endif } #ifndef CONFIG_IMX8M @@ -449,6 +455,47 @@ enum boot_device get_boot_device(void) return boot_dev; } + +bool is_usb_boot(void) +{ + return get_boot_device() == USB_BOOT; +} +#elif defined(CONFIG_MX6) +bool is_usb_boot(void) +{ + unsigned int bmode = readl(&src_base->sbmr2); + u32 reg; + + /* + * Check for BMODE if serial downloader is enabled + * BOOT_MODE - see IMX6DQRM Table 8-1 + */ + if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */ + return true; + + /* + * The above method does not detect that the boot ROM used + * serial downloader in case the boot ROM decided to use the + * serial downloader as a fall back (primary boot source failed). + * + * Infer that the boot ROM used the USB serial downloader by + * checking whether the USB PHY is currently active... This + * assumes that SPL did not (yet) initialize the USB PHY... + */ + if (is_usbotg_phy_active()) + return true; + + reg = (imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT; + + if (reg == IMX6_BMODE_RESERVED) + return true; + return false; +} +#else +bool is_usb_boot(void) +{ + return false; +} #endif #ifdef CONFIG_NXP_BOARD_REVISION diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 317dee9bc191..175179ffb0eb 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -16,8 +16,14 @@ config TARGET_IMX8MQ_EVK select IMX8M select IMX8M_LPDDR4 +config TARGET_IMX8MQ_HB + bool "imx8mq_hb" + select IMX8M + select IMX8M_LPDDR4 + endchoice source "board/freescale/imx8mq_evk/Kconfig" +source "board/solidrun/imx8mq_hb/Kconfig" endif diff --git a/arch/arm/mach-imx/imx8m/Makefile b/arch/arm/mach-imx/imx8m/Makefile index feff4941c1ac..ec6ef3865fd1 100644 --- a/arch/arm/mach-imx/imx8m/Makefile +++ b/arch/arm/mach-imx/imx8m/Makefile @@ -4,3 +4,4 @@ obj-y += lowlevel_init.o obj-y += clock.o clock_slice.o soc.o +obj-$(CONFIG_VIDEO_IMXDCSS) += video_common.o diff --git a/arch/arm/mach-imx/imx8m/clock.c b/arch/arm/mach-imx/imx8m/clock.c index 3766d988ba8d..31049988606d 100644 --- a/arch/arm/mach-imx/imx8m/clock.c +++ b/arch/arm/mach-imx/imx8m/clock.c @@ -373,25 +373,28 @@ void init_wdog_clk(void) clock_enable(CCGR_WDOG3, 1); } -void init_usb_clk(void) +void init_usb_clk(int usbno) { - if (!is_usb_boot()) { - clock_enable(CCGR_USB_CTRL1, 0); - clock_enable(CCGR_USB_CTRL2, 0); - clock_enable(CCGR_USB_PHY1, 0); - clock_enable(CCGR_USB_PHY2, 0); - /* 500MHz */ - clock_set_target_val(USB_BUS_CLK_ROOT, CLK_ROOT_ON | + if (!usbno) { + if (!is_usb_boot()) { + clock_enable(CCGR_USB_CTRL1, 0); + clock_enable(CCGR_USB_PHY1, 0); + clock_enable(CCGR_USB_CTRL2, 0); + clock_enable(CCGR_USB_PHY2, 0); + /* 500MHz */ + clock_set_target_val(USB_BUS_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); - /* 100MHz */ - clock_set_target_val(USB_CORE_REF_CLK_ROOT, CLK_ROOT_ON | + /* 100MHz */ + clock_set_target_val(USB_CORE_REF_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); - /* 100MHz */ - clock_set_target_val(USB_PHY_REF_CLK_ROOT, CLK_ROOT_ON | + /* 100MHz */ + clock_set_target_val(USB_PHY_REF_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); + } clock_enable(CCGR_USB_CTRL1, 1); - clock_enable(CCGR_USB_CTRL2, 1); clock_enable(CCGR_USB_PHY1, 1); + } else { + clock_enable(CCGR_USB_CTRL2, 1); clock_enable(CCGR_USB_PHY2, 1); } } diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 46873aa8ddf3..676fc236ba70 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -77,6 +77,22 @@ static struct mm_region imx8m_mem_map[] = { .size = 0x100000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE + }, { + /* CAAM */ + .virt = 0x100000UL, + .phys = 0x100000UL, + .size = 0x8000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* TCM */ + .virt = 0x7C0000UL, + .phys = 0x7C0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { /* OCRAM */ .virt = 0x900000UL, @@ -167,11 +183,6 @@ int arch_cpu_init(void) return 0; } -bool is_usb_boot(void) -{ - return get_boot_device() == USB_BOOT; -} - #ifdef CONFIG_OF_SYSTEM_SETUP int ft_system_setup(void *blob, bd_t *bd) { @@ -224,3 +235,36 @@ void reset_cpu(ulong addr) */ } } + +#define FSL_SIP_GPC 0xC2000000 +#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03 + +#ifdef CONFIG_USB_XHCI_IMX8M +int imx8m_usb_power(int usb_id, bool on) +{ + unsigned long ret; + + if (usb_id > 1) + return -EINVAL; + + ret = call_imx_sip(FSL_SIP_GPC, + FSL_SIP_CONFIG_GPC_PM_DOMAIN, 2 + usb_id, on, 0); + if (ret) + return -EPERM; + + return 0; +} +#endif + +int imx8m_gpc_power(int id, bool on) +{ + unsigned long ret; + + ret = call_imx_sip(FSL_SIP_GPC, + FSL_SIP_CONFIG_GPC_PM_DOMAIN, id, on, 0); + if (ret) + return -EPERM; + + return 0; +} + diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index ae3734ecb9a5..3d9422d5a219 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -17,8 +17,8 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) if (!boot_private_data) return -EINVAL; - stack = *(ulong *)boot_private_data; - pc = *(ulong *)(boot_private_data + 4); + stack = *(u32 *)boot_private_data; + pc = *(u32 *)(boot_private_data + 4); /* Set the stack and pc to M4 bootROM */ writel(stack, M4_BOOTROM_BASE_ADDR); @@ -26,7 +26,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) /* Enable M4 */ #ifdef CONFIG_IMX8M - call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0); + call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0); #else clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); @@ -38,7 +38,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) int arch_auxiliary_core_check_up(u32 core_id) { #ifdef CONFIG_IMX8M - return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0); + return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0); #else unsigned int val; diff --git a/arch/arm/mach-imx/mx8m/video_common.c b/arch/arm/mach-imx/mx8m/video_common.c new file mode 100644 index 000000000000..cd45c9c81c36 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/video_common.c @@ -0,0 +1,743 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* test congiurations */ +#undef IMXDCSS_LOAD_HDMI_FIRMWARE +#undef IMXDCSS_SET_PIXEL_CLOCK + +static struct video_mode_settings gmode; +static uint32_t gpixfmt; +GraphicDevice panel; +struct video_mode_settings *imx8m_get_gmode(void) +{ + return &gmode; +} + +void imx8m_show_gmode(void) +{ + printf("gmode =\n" + "pixelclock = %u\n" + "xres = %u\n" + "yres = %u\n" + "hfp = %u\n" + "hbp = %u\n" + "vfp = %u\n" + "vbp = %u\n" + "hsync = %u\n" + "vsync = %u\n" + "hpol = %u\n" + "vpol = %u\n", + gmode.pixelclock, + gmode.xres, + gmode.yres, + gmode.hfp, + gmode.hbp, + gmode.vfp, + gmode.vbp, gmode.hsync, gmode.vsync, gmode.hpol, gmode.vpol); +} + +GraphicDevice *imx8m_get_gd(void) +{ + return &panel; +} + +#define REG_BASE_ADDR 0x32e00000UL + +/*#define DEBUGREG*/ +#ifdef DEBUGREG +#define reg32_write(addr, val) \ +do { \ + debug("%s():%d 0x%08x -> 0x%08x\n", __func__, __LINE__, \ + (unsigned int)addr, (unsigned int)val); \ + __raw_writel(val, addr); \ +} while (0) +#else +#define reg32_write(addr, val) __raw_writel(val, addr) +#endif + +#define reg32_read(addr) __raw_readl(addr) + +#define reg32setbit(addr, bitpos) \ + reg32_write((addr), (reg32_read((addr)) | (1<<(bitpos)))) +#define reg32clearbit(addr, bitpos) \ + reg32_write((addr), (reg32_read((addr)) & ~(1<<(bitpos)))) + +#define reg32_read_tst(addr, val, mask) \ +do { \ + u32 temp = reg32_read((addr)); \ + if ((temp & (mask)) == ((val) & (mask))) \ + debug("%s():%d 0x%08x -> 0x%08x\n", \ + __func__, __LINE__, addr, val); \ + else \ + debug("%s():%d 0x%08x -> 0x%08x instead of 0x%08x\n", \ + __func__, __LINE__, addr, temp, val); \ +} while (0) + +#define COLOR_LIST_SIZE 8 +static u32 color_list_argb32[COLOR_LIST_SIZE] = { + 0xFFFFFFFF, /* white */ + 0xFFFF0000, /* red */ + 0xFF00FF00, /* green */ + 0xFF0000FF, /* blue */ + 0xFFFFFF00, /* yellow */ + 0xFF00FFFF, /* cyan */ + 0xFFFF00FF, /* magenta */ + 0xFFC1C2C3, /* silver */ +}; /*AARRGGBB */ + +static unsigned int get_color_index(unsigned short px, unsigned short py, + unsigned short width, unsigned short height, + unsigned short bar_size) +{ + const int mw = 5; /* margin width */ + if ((py >= 0 && py < mw) || (py >= height - mw && py < height) || + (px >= 0 && px < mw) || (px >= width - mw && px < width)) { + return 1; + } + + return py / bar_size; +} + +void imx8m_create_color_bar(void *start_address, + struct video_mode_settings *vms) +{ + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ + uint32_t color_bar_size = vms->yres / COLOR_LIST_SIZE; + int i, j; + u32 *pointer; + int color_index = 0; + pointer = (u32 *)start_address; + uint32_t *color_map = &color_list_argb32[0]; + debug("%s(), %d: start_address %p\n", + __func__, __LINE__, start_address); + debug("%s(), %d: pointer %p\n", __func__, __LINE__, pointer); + debug("%s(), %d x %d\n", __func__, vms->xres, vms->yres); + for (i = 0; i < vms->yres; i++) { + for (j = 0; j < vms->xres; j++) { + color_index = get_color_index(j, i, vms->xres, + vms->yres, + color_bar_size); + *pointer = color_map[color_index]; + pointer++; + } + } + invalidate_dcache_all(); +} + +static void imx8m_set_clocks(int apb_clk, int b_clk, int hdmi_core_clk, + int p_clk, int rtr_clk) +{ + struct ccm_reg *ccm_reg = (struct ccm_reg *)CCM_BASE_ADDR; + + if (b_clk == 800) { + /* b_clk: bus_clk_root(4) sel 2nd input source and + pre_div to 0; output should be 800M */ + reg32_write(&ccm_reg->bus_root[4].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[4].target_root_set, (0x2 << 24)); + } else { + printf("b_clk does not match a supported frequency"); + } + if (rtr_clk == 400) { + /* rtr_clk: bus_clk_root(6) sel 1st input source + and pre_div to 1; output should be 400M */ + reg32_write(&ccm_reg->bus_root[6].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[6].target_root_set, + (0x1 << 24) | (0x1 << 16)); + } else { + debug("rtr_clk does not match a supported frequency"); + } + +#ifdef IMXDCSS_LOAD_HDMI_FIRMWARE + /* If ROM is loading HDMI firmware then this clock should not be set */ + if (hdmi_core_clk == 200) { + /* hdmi_core_clk: ip_clk_root(69) sel 1st input source and + pre_div to 0 */ + reg32_write(&ccm_reg->bus_root[69].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[69].target_root_set, (0x1 << 24)); + g_hdmi_core_clock = 200000000; + } else { + debug("hdmi_core_clk does not match a supported frequency"); + } +#endif + +#ifdef IMXDCSS_SET_PIXEL_CLOCK + /* This would be needed for MIPI-DSI DCSS display */ + if (p_clk == 27) { + /* p_clk: ip_clk_root(9) sel 1st input source and + pre_div to 1; post_div to 5, output 100M */ + reg32_write(&ccm_reg->bus_root[9].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[9].target_root_set, + (0x1 << 24) | (29 << 16)); + } else if (p_clk == 100) { + /* p_clk: ip_clk_root(9) sel 1st input source and + pre_div to 1; post_div to 5, output 100M */ + reg32_write(&ccm_reg->bus_root[9].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[9].target_root_set, + (0x1 << 24) | (0x5 << 16)); + } else if (p_clk == 120) { + /* p_clk: ip_clk_root(9) sel 1st input source and + pre_div to 1; post_div to 4, output 120M */ + reg32_write(&ccm_reg->bus_root[9].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[9].target_root_set, + (0x1 << 24) | (0x4 << 16)); + } else if (p_clk == 200) { + /* I added this to speed up the pixel clock and + get frames out faster. may need to adjust this. + */ + reg32_write(&ccm_reg->bus_root[9].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[9].target_root_set, + (0x4 << 24) | (0x3 << 16)); /*for emu use 800 / 4 */ + } else if (p_clk == 400) { + /* I added this to speed up the pixel clock and + get frames out faster. may need to adjust this. + */ + reg32_write(&ccm_reg->bus_root[9].target_root_clr, + (0x7 << 24) | (0x7 << 16)); + reg32_write(&ccm_reg->bus_root[9].target_root_set, + (0x4 << 24) | (0x1 << 16)); /*for emu use 800 / 2 */ + } else if (p_clk == 40) { /* Do not reprogram, will get 40MHz */ + } else { + debug("p_clk does not match a supported frequency"); + } +#endif +} + +static int imx8m_power_init(uint32_t clock_control) +{ + u32 temp; + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ + + debug("\nenabling display clock...\n"); + clock_enable(CCGR_DISPLAY, 1); + + reg32_write(0x303A00EC, 0x0000ffff); /*PGC_CPU_MAPPING */ + reg32setbit(0x303A00F8, 10); /*PU_PGC_SW_PUP_REQ : disp was 10 */ +#ifdef LOAD_HDMI_FIRMWARE + reg32setbit(0x303A00F8, 9); /*PU_PGC_SW_PUP_REQ : hdmi was 9 */ +#endif + imx8m_set_clocks(133, 800, 200, 27, 400); + + /* DCSS reset */ + reg32_write(0x32e2f000, 0xffffffff); + + /* DCSS clock selection */ + reg32_write(0x32e2f010, clock_control); + temp = reg32_read(0x32e2f010); + debug("%s(): DCSS clock control 0x%08x\n", __func__, temp); + + /* take DCSS out of reset - not needed OFB */ + /*__raw_writel(0xffffffff, 0x32e2f004); */ + + return 0; +} + +static void imx8m_display_init(u64 buffer, int encoding, + struct video_mode_settings *vms) +{ + /*struct video_mode_settings *vms = &vm_settings[g_vm]; */ + + debug("entering %s() ...\n", __func__); + debug("%s() buffer ...\n", __func__); + + /* DTRC-CHAN2/3 */ + reg32_write(REG_BASE_ADDR + 0x160c8, 0x00000002); + reg32_write(REG_BASE_ADDR + 0x170c8, 0x00000002); + + /* CHAN1_DPR */ + reg32_write(REG_BASE_ADDR + 0x180c0, (unsigned int)buffer); + reg32_write(REG_BASE_ADDR + 0x18090, 0x00000002); + reg32_write(REG_BASE_ADDR + 0x180a0, vms->xres); + reg32_write(REG_BASE_ADDR + 0x180b0, vms->yres); + reg32_write(REG_BASE_ADDR + 0x18110, + (unsigned int)buffer + vms->xres * vms->yres); + reg32_write(REG_BASE_ADDR + 0x180f0, 0x00000280); + reg32_write(REG_BASE_ADDR + 0x18100, 0x000000f0); + reg32_write(REG_BASE_ADDR + 0x18070, ((vms->xres * 4) << 16)); + reg32_write(REG_BASE_ADDR + 0x18050, 0x000e4203); + reg32_write(REG_BASE_ADDR + 0x18050, 0x000e4203); + reg32_write(REG_BASE_ADDR + 0x18200, 0x00000038); + reg32_write(REG_BASE_ADDR + 0x18000, 0x00000004); + reg32_write(REG_BASE_ADDR + 0x18000, 0x00000005); + + /* SCALER */ + reg32_write(REG_BASE_ADDR + 0x1c008, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c00c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c010, 0x00000002); + reg32_write(REG_BASE_ADDR + 0x1c014, 0x00000002); + reg32_write(REG_BASE_ADDR + 0x1c018, + ((vms->yres - 1) << 16 | (vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x1c01c, + ((vms->yres - 1) << 16 | (vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x1c020, + ((vms->yres - 1) << 16 | (vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x1c024, + ((vms->yres - 1) << 16 | (vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x1c028, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c02c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c030, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c034, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c038, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c03c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c040, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c044, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c048, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c04c, 0x00002000); + reg32_write(REG_BASE_ADDR + 0x1c050, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c054, 0x00002000); + reg32_write(REG_BASE_ADDR + 0x1c058, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c05c, 0x00002000); + reg32_write(REG_BASE_ADDR + 0x1c060, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c064, 0x00002000); + reg32_write(REG_BASE_ADDR + 0x1c080, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0c0, 0x00040000); + reg32_write(REG_BASE_ADDR + 0x1c100, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c084, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0c4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c104, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c088, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0c8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c108, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c08c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0cc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c10c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c090, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0d0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c110, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c094, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0d4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c114, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c098, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0d8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c118, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c09c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0dc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c11c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0a0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0e0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c120, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0a4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0e4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c124, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0a8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0e8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c128, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0ac, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0ec, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c12c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0b0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0f0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c130, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0b4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0f4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c134, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0b8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0f8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c138, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0bc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c0fc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c13c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c140, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c180, 0x00040000); + reg32_write(REG_BASE_ADDR + 0x1c1c0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c144, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c184, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1c4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c148, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c188, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1c8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c14c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c18c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1cc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c150, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c190, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1d0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c154, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c194, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1d4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c158, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c198, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1d8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c15c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c19c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1dc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c160, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1a0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1e0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c164, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1a4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1e4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c168, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1a8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1e8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c16c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1ac, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1ec, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c170, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1b0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1f0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c174, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1b4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1f4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c178, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1b8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1f8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c17c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1bc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c1fc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c300, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c340, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c380, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c304, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c344, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c384, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c308, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c348, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c388, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c30c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c34c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c38c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c310, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c350, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c390, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c314, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c354, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c394, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c318, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c358, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c398, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c31c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c35c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c39c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c320, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c360, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3a0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c324, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c364, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3a4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c328, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c368, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3a8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c32c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c36c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3ac, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c330, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c370, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3b0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c334, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c374, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3b4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c338, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c378, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3b8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c33c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c37c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c3bc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c200, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c240, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c280, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c204, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c244, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c284, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c208, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c248, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c288, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c20c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c24c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c28c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c210, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c250, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c290, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c214, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c254, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c294, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c218, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c258, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c298, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c21c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c25c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c29c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c220, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c260, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2a0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c224, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c264, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2a4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c228, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c268, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2a8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c22c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c26c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2ac, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c230, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c270, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2b0, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c234, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c274, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2b4, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c238, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c278, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2b8, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c23c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c27c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2bc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c2bc, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x1c000, 0x00000011); + + /* SUBSAM */ + reg32_write(REG_BASE_ADDR + 0x1b070, 0x21612161); + reg32_write(REG_BASE_ADDR + 0x1b080, 0x03ff0000); + reg32_write(REG_BASE_ADDR + 0x1b090, 0x03ff0000); + + reg32_write(REG_BASE_ADDR + 0x1b010, + (((vms->vfp + vms->vbp + vms->vsync + vms->yres - + 1) << 16) | (vms->hfp + vms->hbp + vms->hsync + + vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x1b020, + (((vms->hsync - 1) << 16) | vms->hpol << 31 | (vms->hfp + + vms->hbp + + vms->hsync + + vms->xres - + 1))); + reg32_write(REG_BASE_ADDR + 0x1b030, + (((vms->vfp + vms->vsync - + 1) << 16) | vms->vpol << 31 | (vms->vfp - 1))); + + reg32_write(REG_BASE_ADDR + 0x1b040, + ((1 << 31) | ((vms->vsync + vms->vfp + vms->vbp) << 16) | + (vms->hsync + vms->hbp - 1))); + reg32_write(REG_BASE_ADDR + 0x1b050, + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); + + /* subsample mode 0 none, 1 422, 2 420 */ + switch (encoding) { + case 4: + reg32_write(REG_BASE_ADDR + 0x1b060, 0x00000001); + break; + + case 8: + reg32_write(REG_BASE_ADDR + 0x1b060, 0x00000002); + break; + + case 2: + case 1: + default: + reg32_write(REG_BASE_ADDR + 0x1b060, 0x0000000); + } + + reg32_write(REG_BASE_ADDR + 0x1b000, 0x00000001); +#if 0 + /* not needed for splash setup */ + /* HDR10 Chan3 LUT */ + reg32_write(REG_BASE_ADDR + 0x03874, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x03080, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x03000, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x03800, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x07874, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x07080, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x07000, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x07800, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0b874, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0b080, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0b000, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0b800, 0x00000000); + + /* HDR10 Tables and Registers */ + /*reg32_write(REG_BASE_ADDR+0x0f074, 0x00000003); */ + /*reg32_write(REG_BASE_ADDR+0x0f000, 0x00000004); */ + + reg32_write(REG_BASE_ADDR + 0x0f004, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f008, 0x00000001); + reg32_write(REG_BASE_ADDR + 0x0f00c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f010, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f014, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f018, 0x00000001); + reg32_write(REG_BASE_ADDR + 0x0f01c, 0x00000001); + reg32_write(REG_BASE_ADDR + 0x0f020, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f024, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f028, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f02c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f030, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f034, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f038, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f03c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f040, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f044, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f048, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f04c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f050, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f054, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f058, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f05c, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f060, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f064, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f068, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f06c, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f070, 0xffffffff); + reg32_write(REG_BASE_ADDR + 0x0f074, 0x00000000); + reg32_write(REG_BASE_ADDR + 0x0f000, 0x00000003); +#endif + /* DTG */ + /*reg32_write(REG_BASE_ADDR + 0x20000, 0xff000484); */ + /* disable local alpha */ + reg32_write(REG_BASE_ADDR + 0x20000, 0xff005084); + reg32_write(REG_BASE_ADDR + 0x20004, + (((vms->vfp + vms->vbp + vms->vsync + vms->yres - + 1) << 16) | (vms->hfp + vms->hbp + vms->hsync + + vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x20008, + (((vms->vsync + vms->vfp + vms->vbp - + 1) << 16) | (vms->hsync + vms->hbp - 1))); + reg32_write(REG_BASE_ADDR + 0x2000c, + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x20010, + (((vms->vsync + vms->vfp + vms->vbp - + 1) << 16) | (vms->hsync + vms->hbp - 1))); + reg32_write(REG_BASE_ADDR + 0x20014, + (((vms->vsync + vms->vfp + vms->vbp + vms->yres - + 1) << 16) | (vms->hsync + vms->hbp + vms->xres - 1))); + reg32_write(REG_BASE_ADDR + 0x20028, 0x000b000a); + + /* disable local alpha */ + reg32_write(REG_BASE_ADDR + 0x20000, 0xff005184); + + debug("leaving %s() ...\n", __func__); +} + +void imx8m_display_shutdown(void) +{ + /* stop the DCSS modules in use */ + /* dtg */ + reg32_write(REG_BASE_ADDR + 0x20000, 0); + /* scaler */ + reg32_write(REG_BASE_ADDR + 0x1c000, 0); + reg32_write(REG_BASE_ADDR + 0x1c400, 0); + reg32_write(REG_BASE_ADDR + 0x1c800, 0); + /* dpr */ + reg32_write(REG_BASE_ADDR + 0x18000, 0); + reg32_write(REG_BASE_ADDR + 0x19000, 0); + reg32_write(REG_BASE_ADDR + 0x1a000, 0); + /* sub-sampler*/ + reg32_write(REG_BASE_ADDR + 0x1b000, 0); +#if 0 + /* reset the DCSS */ + reg32_write(0x32e2f000, 0xffffe8); + udelay(100); + reg32_write(0x32e2f000, 0xffffff); +#endif + +} +void *video_hw_init(void) +{ + void *fb; + int encoding = 1; + int ret; + + debug("%s()\n", __func__); + + imx8m_power_init(0x1); + + panel.winSizeX = gmode.xres; + panel.winSizeY = gmode.yres; + panel.plnSizeX = gmode.xres; + panel.plnSizeY = gmode.yres; + panel.gdfBytesPP = 4; + panel.gdfIndex = GDF_32BIT_X888RGB; + panel.memSize = gmode.xres * gmode.yres * panel.gdfBytesPP; + + /* Allocate framebuffer */ + fb = memalign(0x1000, roundup(panel.memSize, 0x1000)); + debug("%s(): fb %p\n", __func__, fb); + if (!fb) { + printf("%s, %s(): Error allocating framebuffer!\n", + __FILE__, __func__); + return NULL; + } + + imx8m_create_color_bar((void *)((uint64_t) fb), &gmode); + + ret = imx8_hdmi_enable(encoding, &gmode); /* may change gmode */ + if (ret) { + printf("HDMI enable failed!\n"); + return NULL; + } + + /* start dccs */ + imx8m_display_init((uint64_t) fb, encoding, &gmode); + + panel.frameAdrs = (ulong) fb; + debug("IMXDCSS display started ...\n"); + + return &panel; +} + +void imx8m_fb_disable(void) +{ + debug("%s()\n", __func__); + if (panel.frameAdrs) { +#ifdef CONFIG_VIDEO_IMX8_HDMI + imx8_hdmi_disable(); +#endif + imx8m_display_shutdown(); + } + +} + +int imx8m_fb_init(struct fb_videomode const *mode, + uint8_t disp, uint32_t pixfmt) +{ + debug("entering %s()\n", __func__); + + if (disp > 1) { + debug("Invalid disp parameter %d for imxdcss_fb_init()\n", + disp); + return -EINVAL; + } + + memset(&gmode, 0, sizeof(struct video_mode_settings)); + gmode.pixelclock = PS2KHZ(mode->pixclock) * 1000; + gmode.xres = mode->xres; + gmode.hbp = mode->left_margin; + gmode.hfp = mode->right_margin; + + gmode.yres = mode->yres; + gmode.vbp = mode->upper_margin; + gmode.vfp = mode->lower_margin; + + gmode.hsync = mode->hsync_len; + gmode.vsync = mode->vsync_len; + gmode.hpol = (mode->flag & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0; + gmode.vpol = (mode->flag & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0; + gpixfmt = pixfmt; + + debug("leaving %s()\n", __func__); + + return 0; +} diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c index 813c2ae5e11c..db8c7e5f9c51 100644 --- a/arch/arm/mach-imx/sip.c +++ b/arch/arm/mach-imx/sip.c @@ -7,7 +7,8 @@ #include unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2) + unsigned long reg1, unsigned long reg2, + unsigned long reg3) { struct pt_regs regs; @@ -15,6 +16,7 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0, regs.regs[1] = reg0; regs.regs[2] = reg1; regs.regs[3] = reg2; + regs.regs[4] = reg3; smc_call(®s); diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 02b69bd24d7a..2df4600a19c3 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -41,8 +41,9 @@ u32 spl_boot_device(void) * checking whether the USB PHY is currently active... This * assumes that SPL did not (yet) initialize the USB PHY... */ - if (is_usbotg_phy_active()) + if (is_usbotg_phy_active()) { return BOOT_DEVICE_BOARD; + } /* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */ switch ((reg & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT) { @@ -119,8 +120,10 @@ u32 spl_boot_device(void) * checking whether the USB PHY is currently active... This * assumes that SPL did not (yet) initialize the USB PHY... */ - if (is_boot_from_usb()) + if (is_boot_from_usb()) { + printf("USB Phy Active Boot Board\n"); return BOOT_DEVICE_BOARD; + } #endif enum boot_device boot_device_spl = get_boot_device(); diff --git a/arch/arm/mach-imx/video.c b/arch/arm/mach-imx/video.c index b40ce53405ae..a6baaec54881 100644 --- a/arch/arm/mach-imx/video.c +++ b/arch/arm/mach-imx/video.c @@ -3,6 +3,9 @@ #include #include #include +#ifdef CONFIG_VIDEO_IMXDCSS +#include +#endif int board_video_skip(void) { @@ -32,8 +35,13 @@ int board_video_skip(void) } if (i < display_count) { +#if defined(CONFIG_VIDEO_IPUV3) ret = ipuv3_fb_init(&displays[i].mode, displays[i].di ? 1 : 0, displays[i].pixfmt); +#elif defined(CONFIG_VIDEO_IMXDCSS) + ret = imx8m_fb_init(&displays[i].mode, displays[i].bus, + displays[i].pixfmt); +#endif if (!ret) { if (displays[i].enable) displays[i].enable(displays + i); diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index f47273fde9c6..15bb14e45112 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -45,15 +46,60 @@ const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) /* DRAM init code ... */ +#define MV_SIP_DRAM_SIZE 0x82000010 + +static u64 a8k_dram_scan_ap_sz(void) +{ + struct pt_regs pregs; + + pregs.regs[0] = MV_SIP_DRAM_SIZE; + pregs.regs[1] = SOC_REGS_PHY_BASE; + smc_call(&pregs); + + return pregs.regs[0]; +} + +static void a8k_dram_init_banksize(void) +{ + /* + * Config 2 DRAM banks: + * Bank 0 - max size 4G - 1G + * Bank 1 - ram size - 4G + 1G + */ + phys_size_t max_bank0_size = SZ_4G - SZ_1G; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size <= max_bank0_size) { + gd->bd->bi_dram[0].size = gd->ram_size; + return; + } + + gd->bd->bi_dram[0].size = max_bank0_size; + if (CONFIG_NR_DRAM_BANKS > 1) { + gd->bd->bi_dram[1].start = SZ_4G; + gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; + } +} + + int dram_init_banksize(void) { - fdtdec_setup_memory_banksize(); + if (CONFIG_IS_ENABLED(ARMADA_8K)) + a8k_dram_init_banksize(); + else + fdtdec_setup_memory_banksize(); return 0; } int dram_init(void) { + if (CONFIG_IS_ENABLED(ARMADA_8K)) { + gd->ram_size = a8k_dram_scan_ap_sz(); + if (gd->ram_size != 0) + return 0; + } + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c index 5c9467bfe8be..62142821a595 100644 --- a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c +++ b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c @@ -6,11 +6,10 @@ #include #include #include +#include #include #include -#define SZ_4G 0x100000000ULL - /* * Size of a region that's large enough to hold the relocated U-Boot and all * other allocations made around it (stack, heap, page tables, etc.) diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig index 8b89c10aba6c..4982ccb72fab 100644 --- a/board/freescale/common/Kconfig +++ b/board/freescale/common/Kconfig @@ -21,6 +21,12 @@ config CMD_ESBC_VALIDATE esbc_validate - validate signature using RSA verification esbc_halt - put the core in spin loop (Secure Boot Only) +config USB_TCPC + bool "USB Typec port controller simple driver" + default n + help + Enable USB type-c port controller (TCPC) driver + config VOL_MONITOR_LTC3882_READ depends on VID bool "Enable the LTC3882 voltage monitor read" diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index e3c5eaeb7026..e77c035f48d2 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -78,4 +78,7 @@ obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o endif obj-$(CONFIG_CHAIN_OF_TRUST) += fsl_chain_of_trust.o +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_USB_TCPC) += tcpc.o +endif endif diff --git a/board/freescale/common/tcpc.c b/board/freescale/common/tcpc.c new file mode 100644 index 000000000000..b3f11f3b94f5 --- /dev/null +++ b/board/freescale/common/tcpc.c @@ -0,0 +1,953 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include "tcpc.h" + +#ifdef DEBUG +#define tcpc_debug_log(port, fmt, args...) tcpc_log(port, fmt, ##args) +#else +#define tcpc_debug_log(port, fmt, args...) +#endif + +static bool tcpc_pd_sink_check_charging(struct tcpc_port *port); + +static int tcpc_log(struct tcpc_port *port, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vscnprintf(port->log_p, port->log_size, fmt, args); + va_end(args); + + port->log_size -= i; + port->log_p += i; + + return i; +} + +int tcpc_set_cc_to_source(struct tcpc_port *port) +{ + uint8_t valb; + int err; + + if (port == NULL) + return -EINVAL; + + valb = (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT) | + (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT) | + (TCPC_ROLE_CTRL_RP_VAL_DEF << + TCPC_ROLE_CTRL_RP_VAL_SHIFT); + + err = dm_i2c_write(port->i2c_dev, TCPC_ROLE_CTRL, &valb, 1); + if (err) + tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err); + return err; +} + +int tcpc_set_cc_to_sink(struct tcpc_port *port) +{ + uint8_t valb; + int err; + + if (port == NULL) + return -EINVAL; + + valb = (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) | + (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT); + + err = dm_i2c_write(port->i2c_dev, TCPC_ROLE_CTRL, &valb, 1); + if (err) + tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err); + return err; +} + + +int tcpc_set_plug_orientation(struct tcpc_port *port, enum typec_cc_polarity polarity) +{ + uint8_t valb; + int err; + + if (port == NULL) + return -EINVAL; + + err = dm_i2c_read(port->i2c_dev, TCPC_TCPC_CTRL, &valb, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + if (polarity == TYPEC_POLARITY_CC2) + valb |= TCPC_TCPC_CTRL_ORIENTATION; + else + valb &= ~TCPC_TCPC_CTRL_ORIENTATION; + + err = dm_i2c_write(port->i2c_dev, TCPC_TCPC_CTRL, &valb, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err); + return -EIO; + } + + return 0; +} + +int tcpc_get_cc_status(struct tcpc_port *port, enum typec_cc_polarity *polarity, enum typec_cc_state *state) +{ + + uint8_t valb_cc, cc2, cc1; + int err; + + if (port == NULL || polarity == NULL || state == NULL) + return -EINVAL; + + err = dm_i2c_read(port->i2c_dev, TCPC_CC_STATUS, (uint8_t *)&valb_cc, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + tcpc_debug_log(port, "cc status 0x%x\n", valb_cc); + + cc2 = (valb_cc >> TCPC_CC_STATUS_CC2_SHIFT) & TCPC_CC_STATUS_CC2_MASK; + cc1 = (valb_cc >> TCPC_CC_STATUS_CC1_SHIFT) & TCPC_CC_STATUS_CC1_MASK; + + if (valb_cc & TCPC_CC_STATUS_LOOK4CONN) + return -EFAULT; + + *state = TYPEC_STATE_OPEN; + + if (valb_cc & TCPC_CC_STATUS_TERM) { + if (cc2) { + *polarity = TYPEC_POLARITY_CC2; + + switch (cc2) { + case 0x1: + *state = TYPEC_STATE_SNK_DEFAULT; + tcpc_log(port, "SNK.Default on CC2\n"); + break; + case 0x2: + *state = TYPEC_STATE_SNK_POWER15; + tcpc_log(port, "SNK.Power1.5 on CC2\n"); + break; + case 0x3: + *state = TYPEC_STATE_SNK_POWER30; + tcpc_log(port, "SNK.Power3.0 on CC2\n"); + break; + } + } else if (cc1) { + *polarity = TYPEC_POLARITY_CC1; + + switch (cc1) { + case 0x1: + *state = TYPEC_STATE_SNK_DEFAULT; + tcpc_log(port, "SNK.Default on CC1\n"); + break; + case 0x2: + *state = TYPEC_STATE_SNK_POWER15; + tcpc_log(port, "SNK.Power1.5 on CC1\n"); + break; + case 0x3: + *state = TYPEC_STATE_SNK_POWER30; + tcpc_log(port, "SNK.Power3.0 on CC1\n"); + break; + } + } else { + *state = TYPEC_STATE_OPEN; + return -EPERM; + } + + } else { + if (cc2) { + *polarity = TYPEC_POLARITY_CC2; + + switch (cc2) { + case 0x1: + if (cc1 == 0x1) { + *state = TYPEC_STATE_SRC_BOTH_RA; + tcpc_log(port, "SRC.Ra on both CC1 and CC2\n"); + } else if (cc1 == 0x2) { + *state = TYPEC_STATE_SRC_RD_RA; + tcpc_log(port, "SRC.Ra on CC2, SRC.Rd on CC1\n"); + } else if (cc1 == 0x0) { + tcpc_log(port, "SRC.Ra only on CC2\n"); + return -EFAULT; + } else + return -EFAULT; + break; + case 0x2: + if (cc1 == 0x1) { + *state = TYPEC_STATE_SRC_RD_RA; + tcpc_log(port, "SRC.Ra on CC1, SRC.Rd on CC2\n"); + } else if (cc1 == 0x0) { + *state = TYPEC_STATE_SRC_RD; + tcpc_log(port, "SRC.Rd on CC2\n"); + } else + return -EFAULT; + break; + case 0x3: + *state = TYPEC_STATE_SRC_RESERVED; + return -EFAULT; + } + } else if (cc1) { + *polarity = TYPEC_POLARITY_CC1; + + switch (cc1) { + case 0x1: + tcpc_log(port, "SRC.Ra only on CC1\n"); + return -EFAULT; + case 0x2: + *state = TYPEC_STATE_SRC_RD; + tcpc_log(port, "SRC.Rd on CC1\n"); + break; + case 0x3: + *state = TYPEC_STATE_SRC_RESERVED; + return -EFAULT; + } + } else { + *state = TYPEC_STATE_OPEN; + return -EPERM; + } + } + + return 0; +} + +int tcpc_clear_alert(struct tcpc_port *port, uint16_t clear_mask) +{ + int err; + + if (port == NULL) + return -EINVAL; + + err = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&clear_mask, 2); + if (err) { + tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err); + return -EIO; + } + + return 0; +} + +int tcpc_send_command(struct tcpc_port *port, uint8_t command) +{ + int err; + + if (port == NULL) + return -EINVAL; + + err = dm_i2c_write(port->i2c_dev, TCPC_COMMAND, (const uint8_t *)&command, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_write failed, err %d\n", __func__, err); + return -EIO; + } + + return 0; +} + +int tcpc_polling_reg(struct tcpc_port *port, uint8_t reg, + uint8_t reg_width, uint16_t mask, uint16_t value, ulong timeout_ms) +{ + uint16_t val = 0; + int err; + ulong start; + + if (port == NULL) + return -EINVAL; + + tcpc_debug_log(port, "%s reg 0x%x, mask 0x%x, value 0x%x\n", __func__, reg, mask, value); + + /* TCPC registers is 8 bits or 16 bits */ + if (reg_width != 1 && reg_width != 2) + return -EINVAL; + + start = get_timer(0); /* Get current timestamp */ + do { + err = dm_i2c_read(port->i2c_dev, reg, (uint8_t *)&val, reg_width); + if (err) + return -EIO; + + if ((val & mask) == value) + return 0; + } while (get_timer(0) < (start + timeout_ms)); + + return -ETIME; +} + +void tcpc_print_log(struct tcpc_port *port) +{ + if (port == NULL) + return; + + if (port->log_print == port->log_p) /*nothing to output*/ + return; + + printf("%s", port->log_print); + + port->log_print = port->log_p; +} + +int tcpc_setup_dfp_mode(struct tcpc_port *port) +{ + enum typec_cc_polarity pol; + enum typec_cc_state state; + int ret; + + if (port == NULL) + return -EINVAL; + + if (tcpc_pd_sink_check_charging(port)) { + tcpc_log(port, "%s: Can't apply DFP mode when PD is charging\n", + __func__); + return -EPERM; + } + + tcpc_set_cc_to_source(port); + + ret = tcpc_send_command(port, TCPC_CMD_LOOK4CONNECTION); + if (ret) + return ret; + + /* At least wait tCcStatusDelay + tTCPCFilter + tCcTCPCSampleRate (max) = 200us + 500us + ?ms + * PTN5110 datasheet does not contain the sample rate value, according other productions, + * the sample rate is at ms level, about 2 ms -10ms. So wait 100ms should be enough. + */ + mdelay(100); + + ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_CC_STATUS, TCPC_ALERT_CC_STATUS, 100); + if (ret) { + tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_CC_STATUS bit failed, ret = %d\n", + __func__, ret); + return ret; + } + + ret = tcpc_get_cc_status(port, &pol, &state); + tcpc_clear_alert(port, TCPC_ALERT_CC_STATUS); + + if (!ret) { + /* If presenting as Rd/audio mode/open, return */ + if (state != TYPEC_STATE_SRC_RD_RA && state != TYPEC_STATE_SRC_RD) + return -EPERM; + + if (pol == TYPEC_POLARITY_CC1) + tcpc_debug_log(port, "polarity cc1\n"); + else + tcpc_debug_log(port, "polarity cc2\n"); + + if (port->ss_sel_func) + port->ss_sel_func(pol); + + ret = tcpc_set_plug_orientation(port, pol); + if (ret) + return ret; + + /* Enable source vbus default voltage */ + ret = tcpc_send_command(port, TCPC_CMD_SRC_VBUS_DEFAULT); + if (ret) + return ret; + + /* The max vbus on time is 200ms, we add margin 100ms */ + mdelay(300); + + } + + return 0; +} + +int tcpc_setup_ufp_mode(struct tcpc_port *port) +{ + enum typec_cc_polarity pol; + enum typec_cc_state state; + int ret; + + if (port == NULL) + return -EINVAL; + + /* Check if the PD charge is working. If not, need to configure CC role for UFP */ + if (!tcpc_pd_sink_check_charging(port)) { + + /* Disable the source vbus once it is enabled by DFP mode */ + tcpc_disable_src_vbus(port); + + tcpc_set_cc_to_sink(port); + + ret = tcpc_send_command(port, TCPC_CMD_LOOK4CONNECTION); + if (ret) + return ret; + + /* At least wait tCcStatusDelay + tTCPCFilter + tCcTCPCSampleRate (max) = 200us + 500us + ?ms + * PTN5110 datasheet does not contain the sample rate value, according other productions, + * the sample rate is at ms level, about 2 ms -10ms. So wait 100ms should be enough. + */ + mdelay(100); + + ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_CC_STATUS, TCPC_ALERT_CC_STATUS, 100); + if (ret) { + tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_CC_STATUS bit failed, ret = %d\n", + __func__, ret); + return ret; + } + + ret = tcpc_get_cc_status(port, &pol, &state); + tcpc_clear_alert(port, TCPC_ALERT_CC_STATUS); + + } else { + ret = tcpc_get_cc_status(port, &pol, &state); + } + + if (!ret) { + /* If presenting not as sink, then return */ + if (state != TYPEC_STATE_SNK_DEFAULT && state != TYPEC_STATE_SNK_POWER15 && + state != TYPEC_STATE_SNK_POWER30) + return -EPERM; + + if (pol == TYPEC_POLARITY_CC1) + tcpc_debug_log(port, "polarity cc1\n"); + else + tcpc_debug_log(port, "polarity cc2\n"); + + if (port->ss_sel_func) + port->ss_sel_func(pol); + + ret = tcpc_set_plug_orientation(port, pol); + if (ret) + return ret; + } + + return 0; +} + +int tcpc_disable_src_vbus(struct tcpc_port *port) +{ + int ret; + + if (port == NULL) + return -EINVAL; + + /* Disable VBUS*/ + ret = tcpc_send_command(port, TCPC_CMD_DISABLE_SRC_VBUS); + if (ret) + return ret; + + /* The max vbus off time is 0.5ms, we add margin 0.5 ms */ + mdelay(1); + + return 0; +} + +static int tcpc_pd_receive_message(struct tcpc_port *port, struct pd_message *msg) +{ + int ret; + uint8_t cnt; + uint16_t val; + + if (port == NULL) + return -EINVAL; + + /* Generally the max tSenderResponse is 30ms, max tTypeCSendSourceCap is 200ms, we set the timeout to 500ms */ + ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_RX_STATUS, TCPC_ALERT_RX_STATUS, 500); + if (ret) { + tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_RX_STATUS bit failed, ret = %d\n", + __func__, ret); + return ret; + } + + cnt = 0; + ret = dm_i2c_read(port->i2c_dev, TCPC_RX_BYTE_CNT, (uint8_t *)&cnt, 1); + if (ret) + return -EIO; + + if (cnt > 0) { + ret = dm_i2c_read(port->i2c_dev, TCPC_RX_BUF_FRAME_TYPE, (uint8_t *)msg, cnt); + if (ret) + return -EIO; + + /* Clear RX status alert bit */ + val = TCPC_ALERT_RX_STATUS; + ret = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&val, 2); + if (ret) + return -EIO; + } + + return cnt; +} + +static int tcpc_pd_transmit_message(struct tcpc_port *port, struct pd_message *msg_p, uint8_t bytes) +{ + int ret; + uint8_t valb; + uint16_t val; + + if (port == NULL) + return -EINVAL; + + if (msg_p == NULL || bytes <= 0) + return -EINVAL; + + ret = dm_i2c_write(port->i2c_dev, TCPC_TX_BYTE_CNT, (const uint8_t *)&bytes, 1); + if (ret) + return -EIO; + + ret = dm_i2c_write(port->i2c_dev, TCPC_TX_HDR, (const uint8_t *)&(msg_p->header), bytes); + if (ret) + return -EIO; + + valb = (3 << TCPC_TRANSMIT_RETRY_SHIFT) | (TCPC_TX_SOP << TCPC_TRANSMIT_TYPE_SHIFT); + ret = dm_i2c_write(port->i2c_dev, TCPC_TRANSMIT, (const uint8_t *)&valb, 1); + if (ret) + return -EIO; + + /* Max tReceive is 1.1ms, we set to 5ms timeout */ + ret = tcpc_polling_reg(port, TCPC_ALERT, 2, TCPC_ALERT_TX_SUCCESS, TCPC_ALERT_TX_SUCCESS, 5); + if (ret) { + if (ret == -ETIME) { + ret = dm_i2c_read(port->i2c_dev, TCPC_ALERT, (uint8_t *)&val, 2); + if (ret) + return -EIO; + + if (val & TCPC_ALERT_TX_FAILED) + tcpc_log(port, "%s: PD TX FAILED, ALERT = 0x%x\n", __func__, val); + + if (val & TCPC_ALERT_TX_DISCARDED) + tcpc_log(port, "%s: PD TX DISCARDED, ALERT = 0x%x\n", __func__, val); + + } else { + tcpc_log(port, "%s: Polling ALERT register, TCPC_ALERT_TX_SUCCESS bit failed, ret = %d\n", + __func__, ret); + } + } else { + port->tx_msg_id = (port->tx_msg_id + 1) & PD_HEADER_ID_MASK; + } + + /* Clear ALERT status */ + val &= (TCPC_ALERT_TX_FAILED | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_SUCCESS); + ret = dm_i2c_write(port->i2c_dev, TCPC_ALERT, (const uint8_t *)&val, 2); + if (ret) + return -EIO; + + return ret; +} + +static void tcpc_log_source_caps(struct tcpc_port *port, uint32_t *caps, unsigned int capcount) +{ + int i; + + for (i = 0; i < capcount; i++) { + u32 pdo = caps[i]; + enum pd_pdo_type type = pdo_type(pdo); + + tcpc_log(port, "PDO %d: type %d, ", + i, type); + + switch (type) { + case PDO_TYPE_FIXED: + tcpc_log(port, "%u mV, %u mA [%s%s%s%s%s%s]\n", + pdo_fixed_voltage(pdo), + pdo_max_current(pdo), + (pdo & PDO_FIXED_DUAL_ROLE) ? + "R" : "", + (pdo & PDO_FIXED_SUSPEND) ? + "S" : "", + (pdo & PDO_FIXED_HIGHER_CAP) ? + "H" : "", + (pdo & PDO_FIXED_USB_COMM) ? + "U" : "", + (pdo & PDO_FIXED_DATA_SWAP) ? + "D" : "", + (pdo & PDO_FIXED_EXTPOWER) ? + "E" : ""); + break; + case PDO_TYPE_VAR: + tcpc_log(port, "%u-%u mV, %u mA\n", + pdo_min_voltage(pdo), + pdo_max_voltage(pdo), + pdo_max_current(pdo)); + break; + case PDO_TYPE_BATT: + tcpc_log(port, "%u-%u mV, %u mW\n", + pdo_min_voltage(pdo), + pdo_max_voltage(pdo), + pdo_max_power(pdo)); + break; + default: + tcpc_log(port, "undefined\n"); + break; + } + } +} + +static int tcpc_pd_select_pdo(uint32_t *caps, uint32_t capcount, uint32_t max_snk_mv, uint32_t max_snk_ma) +{ + unsigned int i, max_mw = 0, max_mv = 0; + int ret = -EINVAL; + + /* + * Select the source PDO providing the most power while staying within + * the board's voltage limits. Prefer PDO providing exp + */ + for (i = 0; i < capcount; i++) { + u32 pdo = caps[i]; + enum pd_pdo_type type = pdo_type(pdo); + unsigned int mv, ma, mw; + + if (type == PDO_TYPE_FIXED) + mv = pdo_fixed_voltage(pdo); + else + mv = pdo_min_voltage(pdo); + + if (type == PDO_TYPE_BATT) { + mw = pdo_max_power(pdo); + } else { + ma = min(pdo_max_current(pdo), + max_snk_ma); + mw = ma * mv / 1000; + } + + /* Perfer higher voltages if available */ + if ((mw > max_mw || (mw == max_mw && mv > max_mv)) && + mv <= max_snk_mv) { + ret = i; + max_mw = mw; + max_mv = mv; + } + } + + return ret; +} + +static int tcpc_pd_build_request(struct tcpc_port *port, + uint32_t *caps, + uint32_t capcount, + uint32_t max_snk_mv, + uint32_t max_snk_ma, + uint32_t max_snk_mw, + uint32_t operating_snk_mw, + uint32_t *rdo) +{ + unsigned int mv, ma, mw, flags; + unsigned int max_ma, max_mw; + enum pd_pdo_type type; + int index; + u32 pdo; + + index = tcpc_pd_select_pdo(caps, capcount, max_snk_mv, max_snk_ma); + if (index < 0) + return -EINVAL; + + pdo = caps[index]; + type = pdo_type(pdo); + + if (type == PDO_TYPE_FIXED) + mv = pdo_fixed_voltage(pdo); + else + mv = pdo_min_voltage(pdo); + + /* Select maximum available current within the board's power limit */ + if (type == PDO_TYPE_BATT) { + mw = pdo_max_power(pdo); + ma = 1000 * min(mw, max_snk_mw) / mv; + } else { + ma = min(pdo_max_current(pdo), + 1000 * max_snk_mw / mv); + } + ma = min(ma, max_snk_ma); + + /* XXX: Any other flags need to be set? */ + flags = 0; + + /* Set mismatch bit if offered power is less than operating power */ + mw = ma * mv / 1000; + max_ma = ma; + max_mw = mw; + if (mw < operating_snk_mw) { + flags |= RDO_CAP_MISMATCH; + max_mw = operating_snk_mw; + max_ma = max_mw * 1000 / mv; + } + + if (type == PDO_TYPE_BATT) { + *rdo = RDO_BATT(index + 1, mw, max_mw, flags); + + tcpc_log(port, "Requesting PDO %d: %u mV, %u mW%s\n", + index, mv, mw, + flags & RDO_CAP_MISMATCH ? " [mismatch]" : ""); + } else { + *rdo = RDO_FIXED(index + 1, ma, max_ma, flags); + + tcpc_log(port, "Requesting PDO %d: %u mV, %u mA%s\n", + index, mv, ma, + flags & RDO_CAP_MISMATCH ? " [mismatch]" : ""); + } + + return 0; +} + +static void tcpc_pd_sink_process(struct tcpc_port *port) +{ + int ret; + uint8_t msgtype; + uint32_t objcnt; + struct pd_message msg; + enum pd_sink_state pd_state = WAIT_SOURCE_CAP; + + while (tcpc_pd_receive_message(port, &msg) > 0) { + + msgtype = pd_header_type(msg.header); + objcnt = pd_header_cnt_le(msg.header); + + tcpc_debug_log(port, "get msg, type %d, cnt %d\n", msgtype, objcnt); + + switch (pd_state) { + case WAIT_SOURCE_CAP: + case SINK_READY: + if (msgtype != PD_DATA_SOURCE_CAP) + continue; + + uint32_t *caps = (uint32_t *)&msg.payload; + uint32_t rdo = 0; + + tcpc_log_source_caps(port, caps, objcnt); + + tcpc_pd_build_request(port, caps, objcnt, + port->cfg.max_snk_mv, port->cfg.max_snk_ma, + port->cfg.max_snk_mw, port->cfg.op_snk_mv, + &rdo); + + memset(&msg, 0, sizeof(msg)); + msg.header = PD_HEADER(PD_DATA_REQUEST, 0, 0, port->tx_msg_id, 1); /* power sink, data device, id 0, len 1 */ + msg.payload[0] = rdo; + + ret = tcpc_pd_transmit_message(port, &msg, 6); + if (ret) + tcpc_log(port, "send request failed\n"); + else + pd_state = WAIT_SOURCE_ACCEPT; + + break; + case WAIT_SOURCE_ACCEPT: + if (objcnt > 0) /* Should be ctrl message */ + continue; + + if (msgtype == PD_CTRL_ACCEPT) { + pd_state = WAIT_SOURCE_READY; + tcpc_log(port, "Source accept request\n"); + } else if (msgtype == PD_CTRL_REJECT) { + tcpc_log(port, "Source reject request\n"); + return; + } + + break; + case WAIT_SOURCE_READY: + if (objcnt > 0) /* Should be ctrl message */ + continue; + + if (msgtype == PD_CTRL_PS_RDY) { + tcpc_log(port, "PD source ready!\n"); + pd_state = SINK_READY; + } + + break; + default: + tcpc_log(port, "unexpect status: %u\n", pd_state); + break; + } + } +} + +static bool tcpc_pd_sink_check_charging(struct tcpc_port *port) +{ + uint8_t valb; + int err; + enum typec_cc_polarity pol; + enum typec_cc_state state; + + if (port == NULL) + return false; + + /* Check the CC status, must be sink */ + err = tcpc_get_cc_status(port, &pol, &state); + if (err || (state != TYPEC_STATE_SNK_POWER15 + && state != TYPEC_STATE_SNK_POWER30 + && state != TYPEC_STATE_SNK_DEFAULT)) { + tcpc_debug_log(port, "TCPC wrong state for PD charging, err = %d, CC = 0x%x\n", + err, state); + return false; + } + + /* Check the VBUS PRES and SINK VBUS for dead battery */ + err = dm_i2c_read(port->i2c_dev, TCPC_POWER_STATUS, &valb, 1); + if (err) { + tcpc_debug_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return false; + } + + if (!(valb & TCPC_POWER_STATUS_VBUS_PRES)) { + tcpc_debug_log(port, "VBUS NOT PRES \n"); + return false; + } + + if (!(valb & TCPC_POWER_STATUS_SINKING_VBUS)) { + tcpc_debug_log(port, "SINK VBUS is not enabled for dead battery\n"); + return false; + } + + return true; +} + +static int tcpc_pd_sink_init(struct tcpc_port *port) +{ + uint8_t valb; + uint16_t val; + int err; + enum typec_cc_polarity pol; + enum typec_cc_state state; + + if (port == NULL) + return -EINVAL; + + port->pd_state = UNATTACH; + + /* Check the VBUS PRES and SINK VBUS for dead battery */ + err = dm_i2c_read(port->i2c_dev, TCPC_POWER_STATUS, &valb, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + if (!(valb & TCPC_POWER_STATUS_VBUS_PRES)) { + tcpc_debug_log(port, "VBUS NOT PRES \n"); + return -EPERM; + } + + if (!(valb & TCPC_POWER_STATUS_SINKING_VBUS)) { + tcpc_debug_log(port, "SINK VBUS is not enabled for dead battery\n"); + return -EPERM; + } + + err = dm_i2c_read(port->i2c_dev, TCPC_ALERT, (uint8_t *)&val, 2); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + if (!(val & TCPC_ALERT_CC_STATUS)) { + tcpc_debug_log(port, "CC STATUS not detected for dead battery\n"); + return -EPERM; + } + + err = tcpc_get_cc_status(port, &pol, &state); + if (err || (state != TYPEC_STATE_SNK_POWER15 + && state != TYPEC_STATE_SNK_POWER30 + && state != TYPEC_STATE_SNK_DEFAULT)) { + tcpc_log(port, "TCPC wrong state for dead battery, err = %d, CC = 0x%x\n", + err, state); + return -EPERM; + } else + port->pd_state = ATTACHED; + + dm_i2c_read(port->i2c_dev, TCPC_POWER_CTRL, (uint8_t *)&valb, 1); + valb &= ~TCPC_POWER_CTRL_AUTO_DISCH_DISCO; /* disable AutoDischargeDisconnect */ + dm_i2c_write(port->i2c_dev, TCPC_POWER_CTRL, (const uint8_t *)&valb, 1); + + /* As sink role */ + valb = 0x00; + err = dm_i2c_write(port->i2c_dev, TCPC_MSG_HDR_INFO, (const uint8_t *)&valb, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + /* Enable rx */ + valb = TCPC_RX_DETECT_SOP | TCPC_RX_DETECT_HARD_RESET; + err = dm_i2c_write(port->i2c_dev, TCPC_RX_DETECT, (const uint8_t *)&valb, 1); + if (err) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, err); + return -EIO; + } + + tcpc_pd_sink_process(port); + + return 0; +} + +int tcpc_init(struct tcpc_port *port, struct tcpc_port_config config, ss_mux_sel ss_sel_func) +{ + int ret; + uint8_t valb; + uint16_t vid, pid; + struct udevice *bus; + struct udevice *i2c_dev = NULL; + + memset(port, 0, sizeof(struct tcpc_port)); + + if (port == NULL) + return -EINVAL; + + port->cfg = config; + port->tx_msg_id = 0; + port->ss_sel_func = ss_sel_func; + port->log_p = (char *)&(port->logbuffer); + port->log_size = TCPC_LOG_BUFFER_SIZE; + port->log_print = port->log_p; + memset(&(port->logbuffer), 0, TCPC_LOG_BUFFER_SIZE); + + ret = uclass_get_device_by_seq(UCLASS_I2C, port->cfg.i2c_bus, &bus); + if (ret) { + printf("%s: Can't find bus\n", __func__); + return -EINVAL; + } + + ret = dm_i2c_probe(bus, port->cfg.addr, 0, &i2c_dev); + if (ret) { + printf("%s: Can't find device id=0x%x\n", + __func__, config.addr); + return -ENODEV; + } + + port->i2c_dev = i2c_dev; + + /* Check the Initialization Status bit in 1s */ + ret = tcpc_polling_reg(port, TCPC_POWER_STATUS, 1, TCPC_POWER_STATUS_UNINIT, 0, 1000); + if (ret) { + tcpc_log(port, "%s: Polling TCPC POWER STATUS Initialization Status bit failed, ret = %d\n", + __func__, ret); + return ret; + } + + /* Clear AllRegistersResetToDefault */ + valb = 0x80; + ret = dm_i2c_write(port->i2c_dev, TCPC_FAULT_STATUS, (const uint8_t *)&valb, 1); + if (ret) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret); + return -EIO; + } + + /* Read Vendor ID and Product ID */ + ret = dm_i2c_read(port->i2c_dev, TCPC_VENDOR_ID, (uint8_t *)&vid, 2); + if (ret) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret); + return -EIO; + } + + ret = dm_i2c_read(port->i2c_dev, TCPC_PRODUCT_ID, (uint8_t *)&pid, 2); + if (ret) { + tcpc_log(port, "%s dm_i2c_read failed, err %d\n", __func__, ret); + return -EIO; + } + + tcpc_log(port, "TCPC: Vendor ID [0x%x], Product ID [0x%x]\n", vid, pid); + + if (port->cfg.port_type == TYPEC_PORT_UFP + || port->cfg.port_type == TYPEC_PORT_DRP) + tcpc_pd_sink_init(port); + + tcpc_clear_alert(port, 0xffff); + + tcpc_print_log(port); + + return 0; +} diff --git a/board/freescale/common/tcpc.h b/board/freescale/common/tcpc.h new file mode 100644 index 000000000000..43b5e49394d5 --- /dev/null +++ b/board/freescale/common/tcpc.h @@ -0,0 +1,448 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __TCPCI_H +#define __TCPCI_H + +#include + +#define TCPC_VENDOR_ID 0x0 +#define TCPC_PRODUCT_ID 0x2 + +#define TCPC_ALERT 0x10 +#define TCPC_ALERT_VBUS_DISCNCT BIT(11) +#define TCPC_ALERT_RX_BUF_OVF BIT(10) +#define TCPC_ALERT_FAULT BIT(9) +#define TCPC_ALERT_V_ALARM_LO BIT(8) +#define TCPC_ALERT_V_ALARM_HI BIT(7) +#define TCPC_ALERT_TX_SUCCESS BIT(6) +#define TCPC_ALERT_TX_DISCARDED BIT(5) +#define TCPC_ALERT_TX_FAILED BIT(4) +#define TCPC_ALERT_RX_HARD_RST BIT(3) +#define TCPC_ALERT_RX_STATUS BIT(2) +#define TCPC_ALERT_POWER_STATUS BIT(1) +#define TCPC_ALERT_CC_STATUS BIT(0) + +#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 +#define TCPC_ROLE_CTRL_DRP BIT(6) +#define TCPC_ROLE_CTRL_RP_VAL_SHIFT 4 +#define TCPC_ROLE_CTRL_RP_VAL_MASK 0x3 +#define TCPC_ROLE_CTRL_RP_VAL_DEF 0x0 +#define TCPC_ROLE_CTRL_RP_VAL_1_5 0x1 +#define TCPC_ROLE_CTRL_RP_VAL_3_0 0x2 +#define TCPC_ROLE_CTRL_CC2_SHIFT 2 +#define TCPC_ROLE_CTRL_CC2_MASK 0x3 +#define TCPC_ROLE_CTRL_CC1_SHIFT 0 +#define TCPC_ROLE_CTRL_CC1_MASK 0x3 +#define TCPC_ROLE_CTRL_CC_RA 0x0 +#define TCPC_ROLE_CTRL_CC_RP 0x1 +#define TCPC_ROLE_CTRL_CC_RD 0x2 +#define TCPC_ROLE_CTRL_CC_OPEN 0x3 + +#define TCPC_POWER_CTRL 0x1c +#define TCPC_POWER_CTRL_EN_VCONN BIT(0) +#define TCPC_POWER_CTRL_VCONN_POWER BIT(1) +#define TCPC_POWER_CTRL_FORCE_DISCH BIT(2) +#define TCPC_POWER_CTRL_EN_BLEED_CH BIT(3) +#define TCPC_POWER_CTRL_AUTO_DISCH_DISCO BIT(4) +#define TCPC_POWER_CTRL_DIS_V_ALARMS BIT(5) +#define TCPC_POWER_CTRL_VBUS_V_MONITOR BIT(6) + +#define TCPC_CC_STATUS 0x1d +#define TCPC_CC_STATUS_LOOK4CONN BIT(5) +#define TCPC_CC_STATUS_TERM BIT(4) +#define TCPC_CC_STATUS_CC2_SHIFT 2 +#define TCPC_CC_STATUS_CC2_MASK 0x3 +#define TCPC_CC_STATUS_CC1_SHIFT 0 +#define TCPC_CC_STATUS_CC1_MASK 0x3 + +#define TCPC_POWER_STATUS 0x1e +#define TCPC_POWER_STATUS_UNINIT BIT(6) +#define TCPC_POWER_STATUS_VBUS_DET BIT(3) +#define TCPC_POWER_STATUS_VBUS_PRES BIT(2) +#define TCPC_POWER_STATUS_SINKING_VBUS BIT(0) + +#define TCPC_FAULT_STATUS 0x1f + +#define TCPC_COMMAND 0x23 +#define TCPC_CMD_WAKE_I2C 0x11 +#define TCPC_CMD_DISABLE_VBUS_DETECT 0x22 +#define TCPC_CMD_ENABLE_VBUS_DETECT 0x33 +#define TCPC_CMD_DISABLE_SINK_VBUS 0x44 +#define TCPC_CMD_SINK_VBUS 0x55 +#define TCPC_CMD_DISABLE_SRC_VBUS 0x66 +#define TCPC_CMD_SRC_VBUS_DEFAULT 0x77 +#define TCPC_CMD_SRC_VBUS_HIGH 0x88 +#define TCPC_CMD_LOOK4CONNECTION 0x99 +#define TCPC_CMD_RXONEMORE 0xAA +#define TCPC_CMD_I2C_IDLE 0xFF + +#define TCPC_DEV_CAP_1 0x24 +#define TCPC_DEV_CAP_2 0x26 +#define TCPC_STD_INPUT_CAP 0x28 +#define TCPC_STD_OUTPUT_CAP 0x29 + +#define TCPC_MSG_HDR_INFO 0x2e +#define TCPC_MSG_HDR_INFO_DATA_ROLE BIT(3) +#define TCPC_MSG_HDR_INFO_PWR_ROLE BIT(0) +#define TCPC_MSG_HDR_INFO_REV_SHIFT 1 +#define TCPC_MSG_HDR_INFO_REV_MASK 0x3 + +#define TCPC_RX_DETECT 0x2f +#define TCPC_RX_DETECT_HARD_RESET BIT(5) +#define TCPC_RX_DETECT_SOP BIT(0) + +#define TCPC_RX_BYTE_CNT 0x30 +#define TCPC_RX_BUF_FRAME_TYPE 0x31 +#define TCPC_RX_HDR 0x32 +#define TCPC_RX_DATA 0x34 /* through 0x4f */ + +#define TCPC_TRANSMIT 0x50 +#define TCPC_TRANSMIT_RETRY_SHIFT 4 +#define TCPC_TRANSMIT_RETRY_MASK 0x3 +#define TCPC_TRANSMIT_TYPE_SHIFT 0 +#define TCPC_TRANSMIT_TYPE_MASK 0x7 + +#define TCPC_TX_BYTE_CNT 0x51 +#define TCPC_TX_HDR 0x52 +#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 +#define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG 0x78 + +enum typec_role { + TYPEC_SINK, + TYPEC_SOURCE, + TYPEC_ROLE_UNKNOWN, +}; + +enum typec_data_role { + TYPEC_DEVICE, + TYPEC_HOST, +}; + +enum typec_cc_polarity { + TYPEC_POLARITY_CC1, + TYPEC_POLARITY_CC2, +}; + +enum typec_cc_state { + TYPEC_STATE_OPEN, + TYPEC_STATE_SRC_BOTH_RA, + TYPEC_STATE_SRC_RD_RA, + TYPEC_STATE_SRC_RD, + TYPEC_STATE_SRC_RESERVED, + TYPEC_STATE_SNK_DEFAULT, + TYPEC_STATE_SNK_POWER15, + TYPEC_STATE_SNK_POWER30, +}; + + +/* USB PD Messages */ +enum pd_ctrl_msg_type { + /* 0 Reserved */ + PD_CTRL_GOOD_CRC = 1, + PD_CTRL_GOTO_MIN = 2, + PD_CTRL_ACCEPT = 3, + PD_CTRL_REJECT = 4, + PD_CTRL_PING = 5, + PD_CTRL_PS_RDY = 6, + PD_CTRL_GET_SOURCE_CAP = 7, + PD_CTRL_GET_SINK_CAP = 8, + PD_CTRL_DR_SWAP = 9, + PD_CTRL_PR_SWAP = 10, + PD_CTRL_VCONN_SWAP = 11, + PD_CTRL_WAIT = 12, + PD_CTRL_SOFT_RESET = 13, + /* 14-15 Reserved */ +}; + +enum pd_data_msg_type { + /* 0 Reserved */ + PD_DATA_SOURCE_CAP = 1, + PD_DATA_REQUEST = 2, + PD_DATA_BIST = 3, + PD_DATA_SINK_CAP = 4, + /* 5-14 Reserved */ + PD_DATA_VENDOR_DEF = 15, +}; + +enum tcpc_transmit_type { + TCPC_TX_SOP = 0, + TCPC_TX_SOP_PRIME = 1, + TCPC_TX_SOP_PRIME_PRIME = 2, + TCPC_TX_SOP_DEBUG_PRIME = 3, + TCPC_TX_SOP_DEBUG_PRIME_PRIME = 4, + TCPC_TX_HARD_RESET = 5, + TCPC_TX_CABLE_RESET = 6, + TCPC_TX_BIST_MODE_2 = 7 +}; + +enum pd_sink_state{ + UNATTACH = 0, + ATTACHED, + WAIT_SOURCE_CAP, + WAIT_SOURCE_ACCEPT, + WAIT_SOURCE_READY, + SINK_READY, +}; + + +#define PD_REV10 0x0 +#define PD_REV20 0x1 + +#define PD_HEADER_CNT_SHIFT 12 +#define PD_HEADER_CNT_MASK 0x7 +#define PD_HEADER_ID_SHIFT 9 +#define PD_HEADER_ID_MASK 0x7 +#define PD_HEADER_PWR_ROLE BIT(8) +#define PD_HEADER_REV_SHIFT 6 +#define PD_HEADER_REV_MASK 0x3 +#define PD_HEADER_DATA_ROLE BIT(5) +#define PD_HEADER_TYPE_SHIFT 0 +#define PD_HEADER_TYPE_MASK 0xf + +#define PD_HEADER(type, pwr, data, id, cnt) \ + ((((type) & PD_HEADER_TYPE_MASK) << PD_HEADER_TYPE_SHIFT) | \ + ((pwr) == TYPEC_SOURCE ? PD_HEADER_PWR_ROLE : 0) | \ + ((data) == TYPEC_HOST ? PD_HEADER_DATA_ROLE : 0) | \ + (PD_REV20 << PD_HEADER_REV_SHIFT) | \ + (((id) & PD_HEADER_ID_MASK) << PD_HEADER_ID_SHIFT) | \ + (((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT)) + + +static inline unsigned int pd_header_cnt(uint16_t header) +{ + return (header >> PD_HEADER_CNT_SHIFT) & PD_HEADER_CNT_MASK; +} + +static inline unsigned int pd_header_cnt_le(__le16 header) +{ + return pd_header_cnt(le16_to_cpu(header)); +} + +static inline unsigned int pd_header_type(uint16_t header) +{ + return (header >> PD_HEADER_TYPE_SHIFT) & PD_HEADER_TYPE_MASK; +} + +static inline unsigned int pd_header_type_le(__le16 header) +{ + return pd_header_type(le16_to_cpu(header)); +} + +#define PD_MAX_PAYLOAD 7 + +struct pd_message { + uint8_t frametype; + uint16_t header; + uint32_t payload[PD_MAX_PAYLOAD]; +} __packed; + +enum pd_pdo_type { + PDO_TYPE_FIXED = 0, + PDO_TYPE_BATT = 1, + PDO_TYPE_VAR = 2, +}; + + +#define PDO_TYPE_SHIFT 30 +#define PDO_TYPE_MASK 0x3 + +#define PDO_TYPE(t) ((t) << PDO_TYPE_SHIFT) + +#define PDO_VOLT_MASK 0x3ff +#define PDO_CURR_MASK 0x3ff +#define PDO_PWR_MASK 0x3ff + +#define PDO_FIXED_DUAL_ROLE BIT(29) /* Power role swap supported */ +#define PDO_FIXED_SUSPEND BIT(28) /* USB Suspend supported (Source) */ +#define PDO_FIXED_HIGHER_CAP BIT(28) /* Requires more than vSafe5V (Sink) */ +#define PDO_FIXED_EXTPOWER BIT(27) /* Externally powered */ +#define PDO_FIXED_USB_COMM BIT(26) /* USB communications capable */ +#define PDO_FIXED_DATA_SWAP BIT(25) /* Data role swap supported */ +#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_FIXED_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT) +#define PDO_FIXED_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT) + +#define PDO_FIXED(mv, ma, flags) \ + (PDO_TYPE(PDO_TYPE_FIXED) | (flags) | \ + PDO_FIXED_VOLT(mv) | PDO_FIXED_CURR(ma)) + +#define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ + +#define PDO_BATT_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MIN_VOLT_SHIFT) +#define PDO_BATT_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MAX_VOLT_SHIFT) +#define PDO_BATT_MAX_POWER(mw) ((((mw) / 250) & PDO_PWR_MASK) << PDO_BATT_MAX_PWR_SHIFT) + +#define PDO_BATT(min_mv, max_mv, max_mw) \ + (PDO_TYPE(PDO_TYPE_BATT) | PDO_BATT_MIN_VOLT(min_mv) | \ + PDO_BATT_MAX_VOLT(max_mv) | PDO_BATT_MAX_POWER(max_mw)) + +#define PDO_VAR_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_VAR_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_VAR_MAX_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_VAR_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MIN_VOLT_SHIFT) +#define PDO_VAR_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MAX_VOLT_SHIFT) +#define PDO_VAR_MAX_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_VAR_MAX_CURR_SHIFT) + +#define PDO_VAR(min_mv, max_mv, max_ma) \ + (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \ + PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma)) + +static inline enum pd_pdo_type pdo_type(uint32_t pdo) +{ + return (pdo >> PDO_TYPE_SHIFT) & PDO_TYPE_MASK; +} + +static inline unsigned int pdo_fixed_voltage(uint32_t pdo) +{ + return ((pdo >> PDO_FIXED_VOLT_SHIFT) & PDO_VOLT_MASK) * 50; +} + +static inline unsigned int pdo_min_voltage(uint32_t pdo) +{ + return ((pdo >> PDO_VAR_MIN_VOLT_SHIFT) & PDO_VOLT_MASK) * 50; +} + +static inline unsigned int pdo_max_voltage(uint32_t pdo) +{ + return ((pdo >> PDO_VAR_MAX_VOLT_SHIFT) & PDO_VOLT_MASK) * 50; +} + +static inline unsigned int pdo_max_current(uint32_t pdo) +{ + return ((pdo >> PDO_VAR_MAX_CURR_SHIFT) & PDO_CURR_MASK) * 10; +} + +static inline unsigned int pdo_max_power(uint32_t pdo) +{ + return ((pdo >> PDO_BATT_MAX_PWR_SHIFT) & PDO_PWR_MASK) * 250; +} + +/* RDO: Request Data Object */ +#define RDO_OBJ_POS_SHIFT 28 +#define RDO_OBJ_POS_MASK 0x7 +#define RDO_GIVE_BACK BIT(27) /* Supports reduced operating current */ +#define RDO_CAP_MISMATCH BIT(26) /* Not satisfied by source caps */ +#define RDO_USB_COMM BIT(25) /* USB communications capable */ +#define RDO_NO_SUSPEND BIT(24) /* USB Suspend not supported */ + +#define RDO_PWR_MASK 0x3ff +#define RDO_CURR_MASK 0x3ff + +#define RDO_FIXED_OP_CURR_SHIFT 10 +#define RDO_FIXED_MAX_CURR_SHIFT 0 + +#define RDO_OBJ(idx) (((idx) & RDO_OBJ_POS_MASK) << RDO_OBJ_POS_SHIFT) + +#define PDO_FIXED_OP_CURR(ma) ((((ma) / 10) & RDO_CURR_MASK) << RDO_FIXED_OP_CURR_SHIFT) +#define PDO_FIXED_MAX_CURR(ma) ((((ma) / 10) & RDO_CURR_MASK) << RDO_FIXED_MAX_CURR_SHIFT) + +#define RDO_FIXED(idx, op_ma, max_ma, flags) \ + (RDO_OBJ(idx) | (flags) | \ + PDO_FIXED_OP_CURR(op_ma) | PDO_FIXED_MAX_CURR(max_ma)) + +#define RDO_BATT_OP_PWR_SHIFT 10 /* 250mW units */ +#define RDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ + +#define RDO_BATT_OP_PWR(mw) ((((mw) / 250) & RDO_PWR_MASK) << RDO_BATT_OP_PWR_SHIFT) +#define RDO_BATT_MAX_PWR(mw) ((((mw) / 250) & RDO_PWR_MASK) << RDO_BATT_MAX_PWR_SHIFT) + +#define RDO_BATT(idx, op_mw, max_mw, flags) \ + (RDO_OBJ(idx) | (flags) | \ + RDO_BATT_OP_PWR(op_mw) | RDO_BATT_MAX_PWR(max_mw)) + +static inline unsigned int rdo_index(u32 rdo) +{ + return (rdo >> RDO_OBJ_POS_SHIFT) & RDO_OBJ_POS_MASK; +} + +static inline unsigned int rdo_op_current(u32 rdo) +{ + return ((rdo >> RDO_FIXED_OP_CURR_SHIFT) & RDO_CURR_MASK) * 10; +} + +static inline unsigned int rdo_max_current(u32 rdo) +{ + return ((rdo >> RDO_FIXED_MAX_CURR_SHIFT) & + RDO_CURR_MASK) * 10; +} + +static inline unsigned int rdo_op_power(u32 rdo) +{ + return ((rdo >> RDO_BATT_OP_PWR_SHIFT) & RDO_PWR_MASK) * 250; +} + +static inline unsigned int rdo_max_power(u32 rdo) +{ + return ((rdo >> RDO_BATT_MAX_PWR_SHIFT) & RDO_PWR_MASK) * 250; +} + +#define TCPC_LOG_BUFFER_SIZE 1024 + +typedef void (*ss_mux_sel)(enum typec_cc_polarity pol); + +enum tcpc_port_type { + TYPEC_PORT_DFP, + TYPEC_PORT_UFP, + TYPEC_PORT_DRP, +}; + +struct tcpc_port_config { + uint8_t i2c_bus; + uint8_t addr; + enum tcpc_port_type port_type; + uint32_t max_snk_mv; + uint32_t max_snk_ma; + uint32_t max_snk_mw; + uint32_t op_snk_mv; +}; + +struct tcpc_port { + struct tcpc_port_config cfg; + struct udevice *i2c_dev; + ss_mux_sel ss_sel_func; + enum pd_sink_state pd_state; + uint32_t tx_msg_id; + uint32_t log_size; + char logbuffer[TCPC_LOG_BUFFER_SIZE]; + char *log_p; + char *log_print; +}; + +int tcpc_set_cc_to_source(struct tcpc_port *port); +int tcpc_set_cc_to_sink(struct tcpc_port *port); +int tcpc_set_plug_orientation(struct tcpc_port *port, enum typec_cc_polarity polarity); +int tcpc_get_cc_status(struct tcpc_port *port, enum typec_cc_polarity *polarity, enum typec_cc_state *state); +int tcpc_clear_alert(struct tcpc_port *port, uint16_t clear_mask); +int tcpc_send_command(struct tcpc_port *port, uint8_t command); +int tcpc_polling_reg(struct tcpc_port *port, uint8_t reg, + uint8_t reg_width, uint16_t mask, uint16_t value, ulong timeout_ms); +int tcpc_setup_dfp_mode(struct tcpc_port *port); +int tcpc_setup_ufp_mode(struct tcpc_port *port); +int tcpc_disable_src_vbus(struct tcpc_port *port); +int tcpc_init(struct tcpc_port *port, struct tcpc_port_config config, ss_mux_sel ss_sel_func); +void tcpc_print_log(struct tcpc_port *port); + +#endif /* __TCPCI_H */ diff --git a/board/solidrun/imx8mq_hb/BUILD.md b/board/solidrun/imx8mq_hb/BUILD.md new file mode 100644 index 000000000000..ed82a01adfc4 --- /dev/null +++ b/board/solidrun/imx8mq_hb/BUILD.md @@ -0,0 +1,51 @@ +### Toolchain +You can either build or download a ready-to-use toolchain. An example of such toolchains are from Linaro website. + +When writing this document the following toolchain was used – http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz + +Linaro updates it’s toolchain quite often and more frequent one can be downloaded from here – http://releases.linaro.org/components/toolchain/binaries/ + +Download and extract the toolchain into some place; and as instructed below the CROSS_COMPILE environment variables needs to be set to the path of the toolchain prefex. + +For instance if the toolchain was extracted under /opt/imx8m/toolchain/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu/ then the CROSS_COMPILE needs to be set as follows – +``` +export ARCH=arm64 +export CROSS_COMPILE=/opt/imx8m/toolchain/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu/bin/aarch64-linux-gnu- +``` + +### Download Source and Firmware +``` +git clone https://github.com/SolidRun/arm-trusted-firmware.git -b imx-atf-v1.6 +git clone https://github.com/SolidRun/u-boot.git -b v2018.11-solidrun +wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.9.bin +``` + +### ATF +Building ATF is as follows – *make sure you have set your ARCH and CROSS_COMPILE environment variables as noted above* +``` +cd arm-trusted-firmware +make PLAT=imx8mq bl31 +cp build/imx8mq/release/bl31.bin ../u-boot/ +cd .. +``` + +### Extract and copy firmware +Extract the NXP firmware archive and accept the end user agreement +``` +chmod +x firmware-imx-7.9.bin +./firmware-imx-7.9.bin +cp firmware-imx-7.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin u-boot/ +cp firmware-imx-7.9/firmware-imx-7.9/firmware/ddr/synopsys/lpddr4*.bin u-boot/ +``` + +### U-Boot +Build U-Boot and generate the image - *make sure you have set your ARCH and CROSS_COMPILE environment variables as noted above* +``` +make imx8mq_hb_defconfig +make flash.bin +``` + +### Writing to SD-Card +``` +sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33 +``` diff --git a/board/solidrun/imx8mq_hb/Kconfig b/board/solidrun/imx8mq_hb/Kconfig new file mode 100644 index 000000000000..4420a1be26bf --- /dev/null +++ b/board/solidrun/imx8mq_hb/Kconfig @@ -0,0 +1,14 @@ +if TARGET_IMX8MQ_HB + +config SYS_BOARD + default "imx8mq_hb" + +config SYS_VENDOR + default "solidrun" + +config SYS_CONFIG_NAME + default "imx8mq_hb" + +source "board/freescale/common/Kconfig" + +endif diff --git a/board/solidrun/imx8mq_hb/MAINTAINERS b/board/solidrun/imx8mq_hb/MAINTAINERS new file mode 100644 index 000000000000..789c8cb895a7 --- /dev/null +++ b/board/solidrun/imx8mq_hb/MAINTAINERS @@ -0,0 +1,6 @@ +i.MX8MQ HB BOARD +M: Jon Nettleton +S: Maintained +F: board/solidrun/imx8mq_hb/ +F: include/configs/imx8mq_hb.h +F: configs/imx8mq_hb_defconfig diff --git a/board/solidrun/imx8mq_hb/Makefile b/board/solidrun/imx8mq_hb/Makefile new file mode 100644 index 000000000000..847a9aa51822 --- /dev/null +++ b/board/solidrun/imx8mq_hb/Makefile @@ -0,0 +1,17 @@ +# +# Copyright 2018 Solid-Run Ltd. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += imx8mq_hb.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o +else +obj-$(CONFIG_USB_TCPC) += ../../freescale/common/tcpc.o +endif + +obj-$(CONFIG_POWER_PFUZE100) += ../../freescale/common/pfuze.o +obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += ../../freescale/common/pfuze_dm.o diff --git a/board/solidrun/imx8mq_hb/README b/board/solidrun/imx8mq_hb/README new file mode 100644 index 000000000000..54d8a2cdaed1 --- /dev/null +++ b/board/solidrun/imx8mq_hb/README @@ -0,0 +1,38 @@ +U-Boot for the NXP i.MX8MQ EVK board + +Quick Start +==================== +- Build the ARM Trusted firmware binary +- Get ddr and hdmi fimware +- Build U-Boot +- Boot + +Get and Build the ARM Trusted firmware +==================== +Note: srctree is U-Boot source directory +Get ATF from: https://github.com/SolidRun/arm-trusted-firmware.git +branch: imx-atf-v1.6 +$ make PLAT=imx8mq bl31 +$ cp build/imx8mq/release/bl31.bin $(srctree) + +Get the ddr and hdmi firmware +==================== +Note: srctree is U-Boot source directory +$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.9.bin +$ chmod +x firmware-imx-7.9.bin +$ cp firmware-imx-7.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(srctree) +$ cp firmware-imx-7.9/firmware-imx-7.9/firmware/ddr/synopsys/lpddr4*.bin $(srctree) + +Build U-Boot +==================== +$ export ARCH=arm64 +$ export CROSS_COMPILE=aarch64-poky-linux- +$ make imx8mq_hb_defconfig +$ make flash.bin + +Burn the flash.bin to MicroSD card offset 33KB +$sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33 + +Boot +==================== +Set Boot switch SW801: 1100 and Bmode: 10 to boot from Micro SD. diff --git a/board/solidrun/imx8mq_hb/imx8mq_hb.c b/board/solidrun/imx8mq_hb/imx8mq_hb.c new file mode 100644 index 000000000000..70ca8830b5be --- /dev/null +++ b/board/solidrun/imx8mq_hb/imx8mq_hb.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../freescale/common/pfuze.h" +#include "../../freescale/common/tcpc.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define QSPI_PAD_CTRL (PAD_CTL_DSE2 | PAD_CTL_HYS) + +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) + +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) + +static iomux_v3_cfg_t const wdog_pads[] = { + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +static iomux_v3_cfg_t const uart_pads[] = { + IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +#ifdef CONFIG_FSL_QSPI +static iomux_v3_cfg_t const qspi_pads[] = { + IMX8MQ_PAD_NAND_ALE__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_CE0_B__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL), + + IMX8MQ_PAD_NAND_DATA00__QSPI_A_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA01__QSPI_A_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA02__QSPI_A_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA03__QSPI_A_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL), +}; +#endif + +#ifdef CONFIG_FSL_QSPI +int board_qspi_init(void) +{ + imx_iomux_v3_setup_multiple_pads(qspi_pads, ARRAY_SIZE(qspi_pads)); + + set_clk_qspi(); + + return 0; +} +#endif + +int board_early_init_f(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + set_wdog_reset(wdog); + + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + + return 0; +} + +int dram_init(void) +{ + /* rom_pointer[1] contains the size of TEE occupies */ + if (rom_pointer[1]) + gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; + else + gd->ram_size = PHYS_SDRAM_SIZE; + + return 0; +} + +#ifdef CONFIG_FEC_MXC +#define FEC_RST_PAD IMX_GPIO_NR(1, 9) +static iomux_v3_cfg_t const fec1_rst_pads[] = { + IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec1_rst_pads, + ARRAY_SIZE(fec1_rst_pads)); + + gpio_request(IMX_GPIO_NR(1, 9), "fec1_rst"); + gpio_direction_output(IMX_GPIO_NR(1, 9), 0); + udelay(500); + gpio_direction_output(IMX_GPIO_NR(1, 9), 1); +} + +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + setup_iomux_fec(); + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], BIT(13) | BIT(17), 0); + return set_clk_enet(ENET_125MHZ); +} + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) + +#define USB_PHY_CTRL0 0xF0040 +#define USB_PHY_CTRL0_REF_SSP_EN BIT(2) + +#define USB_PHY_CTRL1 0xF0044 +#define USB_PHY_CTRL1_RESET BIT(0) +#define USB_PHY_CTRL1_COMMONONN BIT(1) +#define USB_PHY_CTRL1_ATERESET BIT(3) +#define USB_PHY_CTRL1_VDATSRCENB0 BIT(19) +#define USB_PHY_CTRL1_VDATDETENB0 BIT(20) + +#define USB_PHY_CTRL2 0xF0048 +#define USB_PHY_CTRL2_TXENABLEN0 BIT(8) + +static struct dwc3_device dwc3_device_data = { + .maximum_speed = USB_SPEED_SUPER, + .base = USB1_BASE_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, + .power_down_scale = 2, +}; + +int usb_gadget_handle_interrupts(void) +{ + dwc3_uboot_handle_interrupt(0); + return 0; +} + +static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3) +{ + u32 RegData; + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 | + USB_PHY_CTRL1_COMMONONN); + RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET; + writel(RegData, dwc3->base + USB_PHY_CTRL1); + + RegData = readl(dwc3->base + USB_PHY_CTRL0); + RegData |= USB_PHY_CTRL0_REF_SSP_EN; + writel(RegData, dwc3->base + USB_PHY_CTRL0); + + RegData = readl(dwc3->base + USB_PHY_CTRL2); + RegData |= USB_PHY_CTRL2_TXENABLEN0; + writel(RegData, dwc3->base + USB_PHY_CTRL2); + + RegData = readl(dwc3->base + USB_PHY_CTRL1); + RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET); + writel(RegData, dwc3->base + USB_PHY_CTRL1); +} +#endif + +#ifdef CONFIG_USB_TCPC +struct tcpc_port port; +struct tcpc_port_config port_config = { + .i2c_bus = 0, + .addr = 0x50, + .port_type = TYPEC_PORT_UFP, + .max_snk_mv = 20000, + .max_snk_ma = 3000, + .max_snk_mw = 15000, + .op_snk_mv = 9000, +}; + +#define USB_TYPEC_SEL IMX_GPIO_NR(3, 15) + +static iomux_v3_cfg_t ss_mux_gpio[] = { + IMX8MQ_PAD_NAND_RE_B__GPIO3_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +void ss_mux_select(enum typec_cc_polarity pol) +{ + if (pol == TYPEC_POLARITY_CC1) + gpio_direction_output(USB_TYPEC_SEL, 1); + else + gpio_direction_output(USB_TYPEC_SEL, 0); +} + +static int setup_typec(void) +{ + int ret; + + imx_iomux_v3_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); + gpio_request(USB_TYPEC_SEL, "typec_sel"); + + ret = tcpc_init(&port, port_config, &ss_mux_select); + if (ret) { + printf("%s: tcpc init failed, err=%d\n", + __func__, ret); + } + + return ret; +} +#endif + +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_IMX8M) +int board_usb_init(int index, enum usb_init_type init) +{ + int ret = 0; + imx8m_usb_power(index, true); + + if (index == 0 && init == USB_INIT_DEVICE) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_setup_ufp_mode(&port); +#endif + dwc3_nxp_usb_phy_init(&dwc3_device_data); + return dwc3_uboot_init(&dwc3_device_data); + } else if (index == 0 && init == USB_INIT_HOST) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_setup_dfp_mode(&port); +#endif + return ret; + } + + return 0; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + int ret = 0; + if (index == 0 && init == USB_INIT_DEVICE) { + dwc3_uboot_exit(index); + } else if (index == 0 && init == USB_INIT_HOST) { +#ifdef CONFIG_USB_TCPC + ret = tcpc_disable_src_vbus(&port); +#endif + } + + imx8m_usb_power(index, false); + + return ret; +} +#endif + +int board_init(void) +{ +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + +#ifdef CONFIG_USB_TCPC + setup_typec(); +#endif + + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, bd_t *bd) +{ + return 0; +} +#endif + +void init_usb_clk(int usbno); + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + env_set("board_name", "HummingBoard Pulse"); + env_set("board_rev", "iMX8MQ"); +#endif + + init_usb_clk(0); + init_usb_clk(1); + + imx8m_gpc_power(10, false); + imx8m_gpc_power(1, false); + + return 0; +} diff --git a/board/solidrun/imx8mq_hb/lpddr4_timing.c b/board/solidrun/imx8mq_hb/lpddr4_timing.c new file mode 100644 index 000000000000..7112cd2c2aa1 --- /dev/null +++ b/board/solidrun/imx8mq_hb/lpddr4_timing.c @@ -0,0 +1,1201 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include + +#define WR_POST_EXT_3200 /* recommened to define */ + +struct dram_cfg_param lpddr4_ddrc_cfg[] = { + /* Start to config, default 3200mbps */ + { DDRC_DBG1(0), 0x00000001 }, + { DDRC_PWRCTL(0), 0x00000001 }, + { DDRC_MSTR(0), 0xa3080020 }, + { DDRC_MSTR2(0), 0x00000000 }, + { DDRC_DERATEEN(0), 0x00000203 }, + { DDRC_DERATEINT(0), 0x0186a000 }, + { DDRC_RFSHTMG(0), 0x006100e0 }, + { DDRC_INIT0(0), 0xc003061c }, + { DDRC_INIT1(0), 0x009E0000 }, + { DDRC_INIT3(0), 0x00d4002d }, +#ifdef WR_POST_EXT_3200 + { DDRC_INIT4(0), 0x00330008 }, +#else + { DDRC_INIT4(0), 0x00310008 }, +#endif + { DDRC_INIT6(0), 0x0066004a }, + { DDRC_INIT7(0), 0x0015004a }, + + { DDRC_DRAMTMG0(0), 0x1a201b22 }, + { DDRC_DRAMTMG1(0), 0x00060633 }, + { DDRC_DRAMTMG2(0), 0x070e1214 }, + { DDRC_DRAMTMG3(0), 0x00c0c000 }, + { DDRC_DRAMTMG4(0), 0x0f04080f }, + { DDRC_DRAMTMG5(0), 0x02040c0c }, + { DDRC_DRAMTMG6(0), 0x01010007 }, + { DDRC_DRAMTMG7(0), 0x00000401 }, + { DDRC_DRAMTMG12(0), 0x00020600 }, + { DDRC_DRAMTMG13(0), 0x0c100002 }, + { DDRC_DRAMTMG14(0), 0x000000e6 }, + { DDRC_DRAMTMG17(0), 0x00a00050 }, + + { DDRC_ZQCTL0(0), 0xc3200018 }, + { DDRC_ZQCTL1(0), 0x028061a8 }, + { DDRC_ZQCTL2(0), 0x00000000 }, + + { DDRC_DFITMG0(0), 0x0497820a }, + { DDRC_DFITMG1(0), 0x00080303 }, + { DDRC_DFIUPD0(0), 0xe0400018 }, + { DDRC_DFIUPD1(0), 0x00df00e4 }, + { DDRC_DFIUPD2(0), 0x80000000 }, + { DDRC_DFIMISC(0), 0x00000011 }, + { DDRC_DFITMG2(0), 0x0000170a }, + + { DDRC_DBICTL(0), 0x00000001 }, + { DDRC_DFIPHYMSTR(0), 0x00000001 }, + { DDRC_RANKCTL(0), 0x00000639 }, + { DDRC_DRAMTMG2(0), 0x070e1214 }, + + { DDRC_ADDRMAP0(0), 0x00000015 }, + { DDRC_ADDRMAP3(0), 0x00000000 }, + { DDRC_ADDRMAP4(0), 0x00001f1f }, + /* bank interleave */ + { DDRC_ADDRMAP1(0), 0x00080808 }, + { DDRC_ADDRMAP5(0), 0x07070707 }, + { DDRC_ADDRMAP6(0), 0x48080707 }, + + /* Frequency 1: 667mts */ + { DDRC_FREQ1_DERATEEN(0), 0x00000001 }, + { DDRC_FREQ1_DERATEINT(0), 0x00518b00 }, + { DDRC_FREQ1_RFSHCTL0(0), 0x0020d040 }, + { DDRC_FREQ1_RFSHTMG(0), 0x0014002f }, + { DDRC_FREQ1_INIT3(0), 0x00940009 }, + { DDRC_FREQ1_INIT4(0), 0x00310000 }, + { DDRC_FREQ1_INIT6(0), 0x0066004a }, + { DDRC_FREQ1_INIT7(0), 0x0016004a }, + { DDRC_FREQ1_DRAMTMG0(0), 0x0b070508 }, + { DDRC_FREQ1_DRAMTMG1(0), 0x0003040b }, + { DDRC_FREQ1_DRAMTMG2(0), 0x0305090c }, + { DDRC_FREQ1_DRAMTMG3(0), 0x00505000 }, + { DDRC_FREQ1_DRAMTMG4(0), 0x04040204 }, + { DDRC_FREQ1_DRAMTMG5(0), 0x02030303 }, + { DDRC_FREQ1_DRAMTMG6(0), 0x01010004 }, + { DDRC_FREQ1_DRAMTMG7(0), 0x00000301 }, + { DDRC_FREQ1_DRAMTMG12(0), 0x00020300 }, + { DDRC_FREQ1_DRAMTMG13(0), 0x0a100002 }, + { DDRC_FREQ1_DRAMTMG14(0), 0x00000031 }, + { DDRC_FREQ1_DRAMTMG17(0), 0x00220011 }, + { DDRC_FREQ1_ZQCTL0(0), 0xc0a70006 }, + { DDRC_FREQ1_DFITMG0(0), 0x3858202 }, + { DDRC_FREQ1_DFITMG1(0), 0x80303 }, + { DDRC_FREQ1_DFITMG2(0), 0x502 }, + + { DDRC_DFITMG0_SHADOW(0), 0x03858202 }, + { DDRC_DFITMG1_SHADOW(0), 0x00080303 }, + { DDRC_DFITMG2_SHADOW(0), 0x00000502 }, + + /* performance setting */ + { DDRC_ODTMAP(0), 0x00000000 }, + { DDRC_SCHED(0), 0x29001505 }, + { DDRC_SCHED1(0), 0x0000002c }, + { DDRC_PERFHPR1(0), 0x5900575b }, + { DDRC_PERFLPR1(0), 0x90000096 }, + { DDRC_PERFWR1(0), 0x1000012c }, + { DDRC_DBG0(0), 0x00000016 }, + { DDRC_DBG1(0), 0x00000000 }, + { DDRC_DBGCMD(0), 0x00000000 }, + { DDRC_SWCTL(0), 0x00000001 }, + { DDRC_POISONCFG(0), 0x00000011 }, + { DDRC_PCCFG(0), 0x00000111 }, + { DDRC_PCFGR_0(0), 0x000010f3 }, + { DDRC_PCFGW_0(0), 0x000072ff }, + { DDRC_PCTRL_0(0), 0x00000001 }, + { DDRC_PCFGQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGQOS1_0(0), 0x0062ffff }, + { DDRC_PCFGWQOS0_0(0), 0x00000e00 }, + { DDRC_PCFGWQOS1_0(0), 0x0000ffff }, +}; + +/* PHY Initialize Configuration */ +struct dram_cfg_param lpddr4_ddrphy_cfg[] = { + { 0x100a0, 0x5 }, + { 0x100a1, 0x7 }, + { 0x100a2, 0x6 }, + { 0x100a3, 0x4 }, + { 0x100a4, 0x2 }, + { 0x100a5, 0x3 }, + { 0x100a6, 0x0 }, + { 0x100a7, 0x1 }, + { 0x110a0, 0x2 }, + { 0x110a1, 0x0 }, + { 0x110a2, 0x6 }, + { 0x110a3, 0x7 }, + { 0x110a4, 0x4 }, + { 0x110a5, 0x5 }, + { 0x110a6, 0x1 }, + { 0x110a7, 0x3 }, + { 0x120a0, 0x5 }, + { 0x120a1, 0x4 }, + { 0x120a2, 0x1 }, + { 0x120a3, 0x3 }, + { 0x120a4, 0x2 }, + { 0x120a5, 0x0 }, + { 0x120a6, 0x7 }, + { 0x120a7, 0x6 }, + { 0x130a0, 0x2 }, + { 0x130a1, 0x5 }, + { 0x130a2, 0x4 }, + { 0x130a3, 0x7 }, + { 0x130a4, 0x6 }, + { 0x130a5, 0x0 }, + { 0x130a6, 0x1 }, + { 0x130a7, 0x3 }, + + { 0x20110, 0x2 }, + { 0x20111, 0x3 }, + { 0x20112, 0x4 }, + { 0x20113, 0x5 }, + { 0x20114, 0x0 }, + { 0x20115, 0x1 }, + + { 0x1005f, 0x1ff }, + { 0x1015f, 0x1ff }, + { 0x1105f, 0x1ff }, + { 0x1115f, 0x1ff }, + { 0x1205f, 0x1ff }, + { 0x1215f, 0x1ff }, + { 0x1305f, 0x1ff }, + { 0x1315f, 0x1ff }, + + { 0x11005f, 0x1ff }, + { 0x11015f, 0x1ff }, + { 0x11105f, 0x1ff }, + { 0x11115f, 0x1ff }, + { 0x11205f, 0x1ff }, + { 0x11215f, 0x1ff }, + { 0x11305f, 0x1ff }, + { 0x11315f, 0x1ff }, + + { 0x55, 0x1ff }, + { 0x1055, 0x1ff }, + { 0x2055, 0x1ff }, + { 0x3055, 0x1ff }, + { 0x4055, 0x1ff }, + { 0x5055, 0x1ff }, + { 0x6055, 0x1ff }, + { 0x7055, 0x1ff }, + { 0x8055, 0x1ff }, + { 0x9055, 0x1ff }, + + { 0x200c5, 0x19 }, + { 0x1200c5, 0x7 }, + + { 0x2002e, 0x2 }, + { 0x12002e, 0x2 }, + + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + +#ifdef WR_POST_EXT_3200 + { 0x20024, 0xeb }, +#else + { 0x20024, 0xab }, +#endif + { 0x2003a, 0x0 }, + { 0x120024, 0xab }, + { 0x2003a, 0x0 }, + { 0x2003a, 0x0 }, + { 0x20056, 0x3 }, + { 0x120056, 0xa }, + { 0x1004d, 0xe00 }, + { 0x1014d, 0xe00 }, + { 0x1104d, 0xe00 }, + { 0x1114d, 0xe00 }, + { 0x1204d, 0xe00 }, + { 0x1214d, 0xe00 }, + { 0x1304d, 0xe00 }, + { 0x1314d, 0xe00 }, + { 0x11004d, 0xe00 }, + { 0x11014d, 0xe00 }, + { 0x11104d, 0xe00 }, + { 0x11114d, 0xe00 }, + { 0x11204d, 0xe00 }, + { 0x11214d, 0xe00 }, + { 0x11304d, 0xe00 }, + { 0x11314d, 0xe00 }, + + { 0x10049, 0xfbe }, + { 0x10149, 0xfbe }, + { 0x11049, 0xfbe }, + { 0x11149, 0xfbe }, + { 0x12049, 0xfbe }, + { 0x12149, 0xfbe }, + { 0x13049, 0xfbe }, + { 0x13149, 0xfbe }, + { 0x110049, 0xfbe }, + { 0x110149, 0xfbe }, + { 0x111049, 0xfbe }, + { 0x111149, 0xfbe }, + { 0x112049, 0xfbe }, + { 0x112149, 0xfbe }, + { 0x113049, 0xfbe }, + { 0x113149, 0xfbe }, + + { 0x43, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x1043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x2043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x3043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x4043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x5043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x6043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x7043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x8043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + { 0x9043, ((LPDDR4_PHY_ADDR_RON << 5) | LPDDR4_PHY_ADDR_RON) }, + + { 0x20018, 0x3 }, + { 0x20075, 0x4 }, + { 0x20050, 0x0 }, + { 0x20008, 0x320 }, + { 0x120008, 0xa7 }, + { 0x20088, 0x9 }, + { 0x200b2, 0xdc }, + { 0x10043, 0x5a1 }, + { 0x10143, 0x5a1 }, + { 0x11043, 0x5a1 }, + { 0x11143, 0x5a1 }, + { 0x12043, 0x5a1 }, + { 0x12143, 0x5a1 }, + { 0x13043, 0x5a1 }, + { 0x13143, 0x5a1 }, + { 0x1200b2, 0xdc }, + { 0x110043, 0x5a1 }, + { 0x110143, 0x5a1 }, + { 0x111043, 0x5a1 }, + { 0x111143, 0x5a1 }, + { 0x112043, 0x5a1 }, + { 0x112143, 0x5a1 }, + { 0x113043, 0x5a1 }, + { 0x113143, 0x5a1 }, + { 0x200fa, 0x1 }, + { 0x1200fa, 0x1 }, + { 0x20019, 0x1 }, + { 0x120019, 0x1 }, + { 0x200f0, 0x0 }, + { 0x200f1, 0x0 }, + { 0x200f2, 0x4444 }, + { 0x200f3, 0x8888 }, + { 0x200f4, 0x5555 }, + { 0x200f5, 0x0 }, + { 0x200f6, 0x0 }, + { 0x200f7, 0xf000 }, + { 0x20025, 0x0 }, + { 0x2002d, 0x0 }, + { 0x12002d, 0x0 }, + { 0x20060, 0x2 }, +}; + +/* P0 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp0_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, /* PHY Ron/Rtt */ + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x131f }, + { 0x54009, LPDDR4_HDT_CTL_3200_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_1d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + + { 0x54019, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK0 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0 }, + { 0x5401f, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT_CA_BANK1 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1 }, + + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + /* MR3/MR2 */ +#ifdef WR_POST_EXT_3200 + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d /*0x312d*/ }, +#else + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d/*0x312d*/ }, +#endif + /* MR11/MR4 */ + { 0x54034, 0x6600 }, + /* self:0x284d//MR13/MR12 */ + { 0x54035, 0x84a }, + /* MR16/MR14*/ + { 0x54036, 0x4a }, + { 0x54037, 0x1500 }, + /* MR1 */ + { 0x54038, 0xd400 }, + /* MR3/MR2 */ +#ifdef WR_POST_EXT_3200 + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d/*0x312d*/ }, +#else + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d/*0x312d*/ }, +#endif + /* MR11/MR4 */ + { 0x5403a, 0x6600 }, + /* self:0x284d//MR13/MR12 */ + { 0x5403b, 0x84a }, + /* MR16/MR14 */ + { 0x5403c, 0x4a }, + { 0x5403d, 0x1500 }, + /* { 0x5403d, 0x500 } */ + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp1_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x1 }, + { 0x54003, 0x29c }, + { 0x54004, 0x2 }, + /* PHY Ron/Rtt */ + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT)/*0x2828*/ }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, LPDDR4_TRAIN_SEQ_400 }, + { 0x54009, LPDDR4_HDT_CTL_400_1D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_400 << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x994 }, + /* MR4/MR3 */ + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1)/*0x31*/ }, + /* MR12/MR11 */ + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ)/*0x4d46*/ }, + /* self:0x4d28//MR14/MR13 */ + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08)/*0x4d08*/ }, + { 0x5401d, 0x0 }, + { 0x5401e, 0x15 }, + { 0x5401f, 0x994 }, + { 0x54020, (((LPDDR4_RON) << 3) | 0x1)/*0x31*/ }, /* MR4/MR3 */ + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | (LPDDR4_RTT_CA << 4) | + LPDDR4_RTT_DQ)/*0x4d46*/ },/* MR12/MR11 */ + /* self:0x4d28//MR14/MR13 */ + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK1 << 8) | 0x08)/*0x4d08*/ }, + { 0x54023, 0x0 }, + { 0x54024, 0x15 }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x9400 }, + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x09 }, + { 0x54034, (((LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (((0 << 5) | (1 << 4) | (0 << 3) | LPDDR4_RTT48) << 8) }, + { 0x54038, 0x9400 }, + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x09 }, + { 0x5403a, (((LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x5403d, (((0 << 5) | (1 << 4) | (0 << 3) | LPDDR4_RTT48) << 8) }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P0 2D message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp0_2d_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xc80 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) }, + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x61 }, + { 0x54009, LPDDR4_HDT_CTL_2D }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, (LPDDR4_CATRAIN_3200_2d << 8) }, + { 0x5400e, 0x0 }, + { 0x5400f, (LPDDR4_2D_SHARE << 8) | 0x00 }, + { 0x54010, LPDDR4_2D_WEIGHT }, + { 0x54011, 0x0 }, + { 0x54012, 0x310 }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x5401a, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x5401a, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x5401b, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) }, + { 0x5401c, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x5401d, 0x0 }, + { 0x5401e, ((0 << 5) | (1 << 4) | (0 << 3) | LPDDR4_RTT48) }, + { 0x5401f, 0x2dd4 }, +#ifdef WR_POST_EXT_3200 + { 0x54020, (((LPDDR4_RON) << 3) | 0x3) }, +#else + { 0x54020, (((LPDDR4_RON) << 3) | 0x1) }, +#endif + { 0x54021, ((LPDDR4_VREF_VALUE_CA << 8) | + (LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) }, + { 0x54022, ((LPDDR4_VREF_VALUE_DQ_RANK0 << 8) | 0x08) }, + { 0x54023, 0x0 }, + { 0x54024, ((0 << 5) | (1 << 4) | (0 << 3) | LPDDR4_RTT48) }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x3 }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + + { 0x54032, 0xd400 }, +#ifdef WR_POST_EXT_3200 + { 0x54033, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, +#else + { 0x54033, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d }, +#endif + { 0x54034, (((LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x54035, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x54036, LPDDR4_VREF_VALUE_DQ_RANK0 }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8) }, + { 0x54038, 0xd400 }, +#ifdef WR_POST_EXT_3200 + { 0x54039, ((((LPDDR4_RON) << 3) | 0x3) << 8) | 0x2d }, +#else + { 0x54039, ((((LPDDR4_RON) << 3) | 0x1) << 8) | 0x2d }, +#endif + { 0x5403a, (((LPDDR4_RTT60 << 4) | LPDDR4_RTT_DQ) << 8) }, + { 0x5403b, (0x0800 | LPDDR4_VREF_VALUE_CA) }, + { 0x5403c, LPDDR4_VREF_VALUE_DQ_RANK1 }, + { 0x5403d, 0x1500 }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* DRAM PHY init engine image */ +struct dram_cfg_param lpddr4_phy_pie[] = { + { 0xd0000, 0x0 }, + { 0x90000, 0x10 }, + { 0x90001, 0x400 }, + { 0x90002, 0x10e }, + { 0x90003, 0x0 }, + { 0x90004, 0x0 }, + { 0x90005, 0x8 }, + { 0x90029, 0xb }, + { 0x9002a, 0x480 }, + { 0x9002b, 0x109 }, + { 0x9002c, 0x8 }, + { 0x9002d, 0x448 }, + { 0x9002e, 0x139 }, + { 0x9002f, 0x8 }, + { 0x90030, 0x478 }, + { 0x90031, 0x109 }, + { 0x90032, 0x0 }, + { 0x90033, 0xe8 }, + { 0x90034, 0x109 }, + { 0x90035, 0x2 }, + { 0x90036, 0x10 }, + { 0x90037, 0x139 }, + { 0x90038, 0xf }, + { 0x90039, 0x7c0 }, + { 0x9003a, 0x139 }, + { 0x9003b, 0x44 }, + { 0x9003c, 0x630 }, + { 0x9003d, 0x159 }, + { 0x9003e, 0x14f }, + { 0x9003f, 0x630 }, + { 0x90040, 0x159 }, + { 0x90041, 0x47 }, + { 0x90042, 0x630 }, + { 0x90043, 0x149 }, + { 0x90044, 0x4f }, + { 0x90045, 0x630 }, + { 0x90046, 0x179 }, + { 0x90047, 0x8 }, + { 0x90048, 0xe0 }, + { 0x90049, 0x109 }, + { 0x9004a, 0x0 }, + { 0x9004b, 0x7c8 }, + { 0x9004c, 0x109 }, + { 0x9004d, 0x0 }, + { 0x9004e, 0x1 }, + { 0x9004f, 0x8 }, + { 0x90050, 0x0 }, + { 0x90051, 0x45a }, + { 0x90052, 0x9 }, + { 0x90053, 0x0 }, + { 0x90054, 0x448 }, + { 0x90055, 0x109 }, + { 0x90056, 0x40 }, + { 0x90057, 0x630 }, + { 0x90058, 0x179 }, + { 0x90059, 0x1 }, + { 0x9005a, 0x618 }, + { 0x9005b, 0x109 }, + { 0x9005c, 0x40c0 }, + { 0x9005d, 0x630 }, + { 0x9005e, 0x149 }, + { 0x9005f, 0x8 }, + { 0x90060, 0x4 }, + { 0x90061, 0x48 }, + { 0x90062, 0x4040 }, + { 0x90063, 0x630 }, + { 0x90064, 0x149 }, + { 0x90065, 0x0 }, + { 0x90066, 0x4 }, + { 0x90067, 0x48 }, + { 0x90068, 0x40 }, + { 0x90069, 0x630 }, + { 0x9006a, 0x149 }, + { 0x9006b, 0x10 }, + { 0x9006c, 0x4 }, + { 0x9006d, 0x18 }, + { 0x9006e, 0x0 }, + { 0x9006f, 0x4 }, + { 0x90070, 0x78 }, + { 0x90071, 0x549 }, + { 0x90072, 0x630 }, + { 0x90073, 0x159 }, + { 0x90074, 0xd49 }, + { 0x90075, 0x630 }, + { 0x90076, 0x159 }, + { 0x90077, 0x94a }, + { 0x90078, 0x630 }, + { 0x90079, 0x159 }, + { 0x9007a, 0x441 }, + { 0x9007b, 0x630 }, + { 0x9007c, 0x149 }, + { 0x9007d, 0x42 }, + { 0x9007e, 0x630 }, + { 0x9007f, 0x149 }, + { 0x90080, 0x1 }, + { 0x90081, 0x630 }, + { 0x90082, 0x149 }, + { 0x90083, 0x0 }, + { 0x90084, 0xe0 }, + { 0x90085, 0x109 }, + { 0x90086, 0xa }, + { 0x90087, 0x10 }, + { 0x90088, 0x109 }, + { 0x90089, 0x9 }, + { 0x9008a, 0x3c0 }, + { 0x9008b, 0x149 }, + { 0x9008c, 0x9 }, + { 0x9008d, 0x3c0 }, + { 0x9008e, 0x159 }, + { 0x9008f, 0x18 }, + { 0x90090, 0x10 }, + { 0x90091, 0x109 }, + { 0x90092, 0x0 }, + { 0x90093, 0x3c0 }, + { 0x90094, 0x109 }, + { 0x90095, 0x18 }, + { 0x90096, 0x4 }, + { 0x90097, 0x48 }, + { 0x90098, 0x18 }, + { 0x90099, 0x4 }, + { 0x9009a, 0x58 }, + { 0x9009b, 0xa }, + { 0x9009c, 0x10 }, + { 0x9009d, 0x109 }, + { 0x9009e, 0x2 }, + { 0x9009f, 0x10 }, + { 0x900a0, 0x109 }, + { 0x900a1, 0x5 }, + { 0x900a2, 0x7c0 }, + { 0x900a3, 0x109 }, + { 0x900a4, 0x10 }, + { 0x900a5, 0x10 }, + { 0x900a6, 0x109 }, + { 0x40000, 0x811 }, + { 0x40020, 0x880 }, + { 0x40040, 0x0 }, + { 0x40060, 0x0 }, + { 0x40001, 0x4008 }, + { 0x40021, 0x83 }, + { 0x40041, 0x4f }, + { 0x40061, 0x0 }, + { 0x40002, 0x4040 }, + { 0x40022, 0x83 }, + { 0x40042, 0x51 }, + { 0x40062, 0x0 }, + { 0x40003, 0x811 }, + { 0x40023, 0x880 }, + { 0x40043, 0x0 }, + { 0x40063, 0x0 }, + { 0x40004, 0x720 }, + { 0x40024, 0xf }, + { 0x40044, 0x1740 }, + { 0x40064, 0x0 }, + { 0x40005, 0x16 }, + { 0x40025, 0x83 }, + { 0x40045, 0x4b }, + { 0x40065, 0x0 }, + { 0x40006, 0x716 }, + { 0x40026, 0xf }, + { 0x40046, 0x2001 }, + { 0x40066, 0x0 }, + { 0x40007, 0x716 }, + { 0x40027, 0xf }, + { 0x40047, 0x2800 }, + { 0x40067, 0x0 }, + { 0x40008, 0x716 }, + { 0x40028, 0xf }, + { 0x40048, 0xf00 }, + { 0x40068, 0x0 }, + { 0x40009, 0x720 }, + { 0x40029, 0xf }, + { 0x40049, 0x1400 }, + { 0x40069, 0x0 }, + { 0x4000a, 0xe08 }, + { 0x4002a, 0xc15 }, + { 0x4004a, 0x0 }, + { 0x4006a, 0x0 }, + { 0x4000b, 0x623 }, + { 0x4002b, 0x15 }, + { 0x4004b, 0x0 }, + { 0x4006b, 0x0 }, + { 0x4000c, 0x4028 }, + { 0x4002c, 0x80 }, + { 0x4004c, 0x0 }, + { 0x4006c, 0x0 }, + { 0x4000d, 0xe08 }, + { 0x4002d, 0xc1a }, + { 0x4004d, 0x0 }, + { 0x4006d, 0x0 }, + { 0x4000e, 0x623 }, + { 0x4002e, 0x1a }, + { 0x4004e, 0x0 }, + { 0x4006e, 0x0 }, + { 0x4000f, 0x4040 }, + { 0x4002f, 0x80 }, + { 0x4004f, 0x0 }, + { 0x4006f, 0x0 }, + { 0x40010, 0x2604 }, + { 0x40030, 0x15 }, + { 0x40050, 0x0 }, + { 0x40070, 0x0 }, + { 0x40011, 0x708 }, + { 0x40031, 0x5 }, + { 0x40051, 0x0 }, + { 0x40071, 0x2002 }, + { 0x40012, 0x8 }, + { 0x40032, 0x80 }, + { 0x40052, 0x0 }, + { 0x40072, 0x0 }, + { 0x40013, 0x2604 }, + { 0x40033, 0x1a }, + { 0x40053, 0x0 }, + { 0x40073, 0x0 }, + { 0x40014, 0x708 }, + { 0x40034, 0xa }, + { 0x40054, 0x0 }, + { 0x40074, 0x2002 }, + { 0x40015, 0x4040 }, + { 0x40035, 0x80 }, + { 0x40055, 0x0 }, + { 0x40075, 0x0 }, + { 0x40016, 0x60a }, + { 0x40036, 0x15 }, + { 0x40056, 0x1200 }, + { 0x40076, 0x0 }, + { 0x40017, 0x61a }, + { 0x40037, 0x15 }, + { 0x40057, 0x1300 }, + { 0x40077, 0x0 }, + { 0x40018, 0x60a }, + { 0x40038, 0x1a }, + { 0x40058, 0x1200 }, + { 0x40078, 0x0 }, + { 0x40019, 0x642 }, + { 0x40039, 0x1a }, + { 0x40059, 0x1300 }, + { 0x40079, 0x0 }, + { 0x4001a, 0x4808 }, + { 0x4003a, 0x880 }, + { 0x4005a, 0x0 }, + { 0x4007a, 0x0 }, + { 0x900a7, 0x0 }, + { 0x900a8, 0x790 }, + { 0x900a9, 0x11a }, + { 0x900aa, 0x8 }, + { 0x900ab, 0x7aa }, + { 0x900ac, 0x2a }, + { 0x900ad, 0x10 }, + { 0x900ae, 0x7b2 }, + { 0x900af, 0x2a }, + { 0x900b0, 0x0 }, + { 0x900b1, 0x7c8 }, + { 0x900b2, 0x109 }, + { 0x900b3, 0x10 }, + { 0x900b4, 0x2a8 }, + { 0x900b5, 0x129 }, + { 0x900b6, 0x8 }, + { 0x900b7, 0x370 }, + { 0x900b8, 0x129 }, + { 0x900b9, 0xa }, + { 0x900ba, 0x3c8 }, + { 0x900bb, 0x1a9 }, + { 0x900bc, 0xc }, + { 0x900bd, 0x408 }, + { 0x900be, 0x199 }, + { 0x900bf, 0x14 }, + { 0x900c0, 0x790 }, + { 0x900c1, 0x11a }, + { 0x900c2, 0x8 }, + { 0x900c3, 0x4 }, + { 0x900c4, 0x18 }, + { 0x900c5, 0xe }, + { 0x900c6, 0x408 }, + { 0x900c7, 0x199 }, + { 0x900c8, 0x8 }, + { 0x900c9, 0x8568 }, + { 0x900ca, 0x108 }, + { 0x900cb, 0x18 }, + { 0x900cc, 0x790 }, + { 0x900cd, 0x16a }, + { 0x900ce, 0x8 }, + { 0x900cf, 0x1d8 }, + { 0x900d0, 0x169 }, + { 0x900d1, 0x10 }, + { 0x900d2, 0x8558 }, + { 0x900d3, 0x168 }, + { 0x900d4, 0x70 }, + { 0x900d5, 0x788 }, + { 0x900d6, 0x16a }, + { 0x900d7, 0x1ff8 }, + { 0x900d8, 0x85a8 }, + { 0x900d9, 0x1e8 }, + { 0x900da, 0x50 }, + { 0x900db, 0x798 }, + { 0x900dc, 0x16a }, + { 0x900dd, 0x60 }, + { 0x900de, 0x7a0 }, + { 0x900df, 0x16a }, + { 0x900e0, 0x8 }, + { 0x900e1, 0x8310 }, + { 0x900e2, 0x168 }, + { 0x900e3, 0x8 }, + { 0x900e4, 0xa310 }, + { 0x900e5, 0x168 }, + { 0x900e6, 0xa }, + { 0x900e7, 0x408 }, + { 0x900e8, 0x169 }, + { 0x900e9, 0x6e }, + { 0x900ea, 0x0 }, + { 0x900eb, 0x68 }, + { 0x900ec, 0x0 }, + { 0x900ed, 0x408 }, + { 0x900ee, 0x169 }, + { 0x900ef, 0x0 }, + { 0x900f0, 0x8310 }, + { 0x900f1, 0x168 }, + { 0x900f2, 0x0 }, + { 0x900f3, 0xa310 }, + { 0x900f4, 0x168 }, + { 0x900f5, 0x1ff8 }, + { 0x900f6, 0x85a8 }, + { 0x900f7, 0x1e8 }, + { 0x900f8, 0x68 }, + { 0x900f9, 0x798 }, + { 0x900fa, 0x16a }, + { 0x900fb, 0x78 }, + { 0x900fc, 0x7a0 }, + { 0x900fd, 0x16a }, + { 0x900fe, 0x68 }, + { 0x900ff, 0x790 }, + { 0x90100, 0x16a }, + { 0x90101, 0x8 }, + { 0x90102, 0x8b10 }, + { 0x90103, 0x168 }, + { 0x90104, 0x8 }, + { 0x90105, 0xab10 }, + { 0x90106, 0x168 }, + { 0x90107, 0xa }, + { 0x90108, 0x408 }, + { 0x90109, 0x169 }, + { 0x9010a, 0x58 }, + { 0x9010b, 0x0 }, + { 0x9010c, 0x68 }, + { 0x9010d, 0x0 }, + { 0x9010e, 0x408 }, + { 0x9010f, 0x169 }, + { 0x90110, 0x0 }, + { 0x90111, 0x8b10 }, + { 0x90112, 0x168 }, + { 0x90113, 0x0 }, + { 0x90114, 0xab10 }, + { 0x90115, 0x168 }, + { 0x90116, 0x0 }, + { 0x90117, 0x1d8 }, + { 0x90118, 0x169 }, + { 0x90119, 0x80 }, + { 0x9011a, 0x790 }, + { 0x9011b, 0x16a }, + { 0x9011c, 0x18 }, + { 0x9011d, 0x7aa }, + { 0x9011e, 0x6a }, + { 0x9011f, 0xa }, + { 0x90120, 0x0 }, + { 0x90121, 0x1e9 }, + { 0x90122, 0x8 }, + { 0x90123, 0x8080 }, + { 0x90124, 0x108 }, + { 0x90125, 0xf }, + { 0x90126, 0x408 }, + { 0x90127, 0x169 }, + { 0x90128, 0xc }, + { 0x90129, 0x0 }, + { 0x9012a, 0x68 }, + { 0x9012b, 0x9 }, + { 0x9012c, 0x0 }, + { 0x9012d, 0x1a9 }, + { 0x9012e, 0x0 }, + { 0x9012f, 0x408 }, + { 0x90130, 0x169 }, + { 0x90131, 0x0 }, + { 0x90132, 0x8080 }, + { 0x90133, 0x108 }, + { 0x90134, 0x8 }, + { 0x90135, 0x7aa }, + { 0x90136, 0x6a }, + { 0x90137, 0x0 }, + { 0x90138, 0x8568 }, + { 0x90139, 0x108 }, + { 0x9013a, 0xb7 }, + { 0x9013b, 0x790 }, + { 0x9013c, 0x16a }, + { 0x9013d, 0x1f }, + { 0x9013e, 0x0 }, + { 0x9013f, 0x68 }, + { 0x90140, 0x8 }, + { 0x90141, 0x8558 }, + { 0x90142, 0x168 }, + { 0x90143, 0xf }, + { 0x90144, 0x408 }, + { 0x90145, 0x169 }, + { 0x90146, 0xc }, + { 0x90147, 0x0 }, + { 0x90148, 0x68 }, + { 0x90149, 0x0 }, + { 0x9014a, 0x408 }, + { 0x9014b, 0x169 }, + { 0x9014c, 0x0 }, + { 0x9014d, 0x8558 }, + { 0x9014e, 0x168 }, + { 0x9014f, 0x8 }, + { 0x90150, 0x3c8 }, + { 0x90151, 0x1a9 }, + { 0x90152, 0x3 }, + { 0x90153, 0x370 }, + { 0x90154, 0x129 }, + { 0x90155, 0x20 }, + { 0x90156, 0x2aa }, + { 0x90157, 0x9 }, + { 0x90158, 0x0 }, + { 0x90159, 0x400 }, + { 0x9015a, 0x10e }, + { 0x9015b, 0x8 }, + { 0x9015c, 0xe8 }, + { 0x9015d, 0x109 }, + { 0x9015e, 0x0 }, + { 0x9015f, 0x8140 }, + { 0x90160, 0x10c }, + { 0x90161, 0x10 }, + { 0x90162, 0x8138 }, + { 0x90163, 0x10c }, + { 0x90164, 0x8 }, + { 0x90165, 0x7c8 }, + { 0x90166, 0x101 }, + { 0x90167, 0x8 }, + { 0x90168, 0x0 }, + { 0x90169, 0x8 }, + { 0x9016a, 0x8 }, + { 0x9016b, 0x448 }, + { 0x9016c, 0x109 }, + { 0x9016d, 0xf }, + { 0x9016e, 0x7c0 }, + { 0x9016f, 0x109 }, + { 0x90170, 0x0 }, + { 0x90171, 0xe8 }, + { 0x90172, 0x109 }, + { 0x90173, 0x47 }, + { 0x90174, 0x630 }, + { 0x90175, 0x109 }, + { 0x90176, 0x8 }, + { 0x90177, 0x618 }, + { 0x90178, 0x109 }, + { 0x90179, 0x8 }, + { 0x9017a, 0xe0 }, + { 0x9017b, 0x109 }, + { 0x9017c, 0x0 }, + { 0x9017d, 0x7c8 }, + { 0x9017e, 0x109 }, + { 0x9017f, 0x8 }, + { 0x90180, 0x8140 }, + { 0x90181, 0x10c }, + { 0x90182, 0x0 }, + { 0x90183, 0x1 }, + { 0x90184, 0x8 }, + { 0x90185, 0x8 }, + { 0x90186, 0x4 }, + { 0x90187, 0x8 }, + { 0x90188, 0x8 }, + { 0x90189, 0x7c8 }, + { 0x9018a, 0x101 }, + { 0x90006, 0x0 }, + { 0x90007, 0x0 }, + { 0x90008, 0x8 }, + { 0x90009, 0x0 }, + { 0x9000a, 0x0 }, + { 0x9000b, 0x0 }, + { 0xd00e7, 0x400 }, + { 0x90017, 0x0 }, + { 0x9001f, 0x2a }, + { 0x90026, 0x6a }, + { 0x400d0, 0x0 }, + { 0x400d1, 0x101 }, + { 0x400d2, 0x105 }, + { 0x400d3, 0x107 }, + { 0x400d4, 0x10f }, + { 0x400d5, 0x202 }, + { 0x400d6, 0x20a }, + { 0x400d7, 0x20b }, + { 0x2003a, 0x2 }, + { 0x2000b, 0x65 }, + { 0x2000c, 0xc9 }, + { 0x2000d, 0x7d1 }, + { 0x2000e, 0x2c }, + { 0x12000b, 0x65 }, + { 0x12000c, 0xc9 }, + { 0x12000d, 0x7d1 }, + { 0x12000e, 0x2c }, + { 0x9000c, 0x0 }, + { 0x9000d, 0x173 }, + { 0x9000e, 0x60 }, + { 0x9000f, 0x6110 }, + { 0x90010, 0x2152 }, + { 0x90011, 0xdfbd }, + { 0x90012, 0x60 }, + { 0x90013, 0x6152 }, + { 0x20010, 0x5a }, + { 0x20011, 0x3 }, + { 0x120010, 0x5a }, + { 0x120011, 0x3 }, + { 0x40080, 0xe0 }, + { 0x40081, 0x12 }, + { 0x40082, 0xe0 }, + { 0x40083, 0x12 }, + { 0x40084, 0xe0 }, + { 0x40085, 0x12 }, + { 0x140080, 0xe0 }, + { 0x140081, 0x12 }, + { 0x140082, 0xe0 }, + { 0x140083, 0x12 }, + { 0x140084, 0xe0 }, + { 0x140085, 0x12 }, + { 0x400fd, 0xf }, + { 0x10011, 0x1 }, + { 0x10012, 0x1 }, + { 0x10013, 0x180 }, + { 0x10018, 0x1 }, + { 0x10002, 0x6209 }, + { 0x100b2, 0x1 }, + { 0x101b4, 0x1 }, + { 0x102b4, 0x1 }, + { 0x103b4, 0x1 }, + { 0x104b4, 0x1 }, + { 0x105b4, 0x1 }, + { 0x106b4, 0x1 }, + { 0x107b4, 0x1 }, + { 0x108b4, 0x1 }, + { 0x11011, 0x1 }, + { 0x11012, 0x1 }, + { 0x11013, 0x180 }, + { 0x11018, 0x1 }, + { 0x11002, 0x6209 }, + { 0x110b2, 0x1 }, + { 0x111b4, 0x1 }, + { 0x112b4, 0x1 }, + { 0x113b4, 0x1 }, + { 0x114b4, 0x1 }, + { 0x115b4, 0x1 }, + { 0x116b4, 0x1 }, + { 0x117b4, 0x1 }, + { 0x118b4, 0x1 }, + { 0x12011, 0x1 }, + { 0x12012, 0x1 }, + { 0x12013, 0x180 }, + { 0x12018, 0x1 }, + { 0x12002, 0x6209 }, + { 0x120b2, 0x1 }, + { 0x121b4, 0x1 }, + { 0x122b4, 0x1 }, + { 0x123b4, 0x1 }, + { 0x124b4, 0x1 }, + { 0x125b4, 0x1 }, + { 0x126b4, 0x1 }, + { 0x127b4, 0x1 }, + { 0x128b4, 0x1 }, + { 0x13011, 0x1 }, + { 0x13012, 0x1 }, + { 0x13013, 0x180 }, + { 0x13018, 0x1 }, + { 0x13002, 0x6209 }, + { 0x130b2, 0x1 }, + { 0x131b4, 0x1 }, + { 0x132b4, 0x1 }, + { 0x133b4, 0x1 }, + { 0x134b4, 0x1 }, + { 0x135b4, 0x1 }, + { 0x136b4, 0x1 }, + { 0x137b4, 0x1 }, + { 0x138b4, 0x1 }, + { 0x2003a, 0x2 }, + { 0xc0080, 0x2 }, + { 0xd0000, 0x1 }, +}; + +struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = lpddr4_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_2d_cfg), + }, +}; + +/* lpddr4 timing config params on EVK board */ +struct dram_timing_info dram_timing = { + .ddrc_cfg = lpddr4_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), + .ddrphy_cfg = lpddr4_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(lpddr4_ddrphy_cfg), + .fsp_msg = lpddr4_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(lpddr4_dram_fsp_msg), + .ddrphy_pie = lpddr4_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), + .fsp_table = { 3200, 667, }, +}; diff --git a/board/solidrun/imx8mq_hb/spl.c b/board/solidrun/imx8mq_hb/spl.c new file mode 100644 index 000000000000..f8b59b1d012c --- /dev/null +++ b/board/solidrun/imx8mq_hb/spl.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../freescale/common/pfuze.h" + +DECLARE_GLOBAL_DATA_PTR; + +extern struct dram_timing_info dram_timing; + +void spl_dram_init(void) +{ + /* ddr init */ + ddr_init(&dram_timing); +} + +#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC, + .gp = IMX_GPIO_NR(5, 14), + }, + .sda = { + .i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC, + .gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC, + .gp = IMX_GPIO_NR(5, 15), + }, +}; + +#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12) +#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10) +#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19) + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = 1; + break; + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + return ret; + } + + return 1; +} + +#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ + PAD_CTL_FSEL2) +#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1) + +static iomux_v3_cfg_t const usdhc1_pads[] = { + IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */ + IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */ + IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC1_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, +}; + +int board_mmc_init(bd_t *bis) +{ + int i, ret; + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc1 USDHC2 + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + init_clk_usdhc(0); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads(usdhc1_pads, + ARRAY_SIZE(usdhc1_pads)); + gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset"); + gpio_direction_output(USDHC1_PWR_GPIO, 0); + udelay(500); + gpio_direction_output(USDHC1_PWR_GPIO, 1); + break; + case 1: + init_clk_usdhc(1); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads(usdhc2_pads, + ARRAY_SIZE(usdhc2_pads)); + break; + default: + printf("Warning: you configured more USDHC controllers(%d) than supported by the board\n", i + 1); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } + + return 0; +} + +#ifdef CONFIG_POWER +#define I2C_PMIC 0 +int power_init_board(void) +{ + struct pmic *p; + int ret; + unsigned int reg; + + ret = power_pfuze100_init(I2C_PMIC); + if (ret) + return -ENODEV; + + p = pmic_get("PFUZE100"); + ret = pmic_probe(p); + if (ret) + return -ENODEV; + + pmic_reg_read(p, PFUZE100_DEVICEID, ®); + printf("PMIC: PFUZE100 ID=0x%02x\n", reg); + + pmic_reg_read(p, PFUZE100_SW3AVOL, ®); + if ((reg & 0x3f) != 0x18) { + reg &= ~0x3f; + reg |= 0x18; + pmic_reg_write(p, PFUZE100_SW3AVOL, reg); + } + + ret = pfuze_mode_init(p, APS_PFM); + if (ret < 0) + return ret; + + /* set SW3A standby mode to off */ + pmic_reg_read(p, PFUZE100_SW3AMODE, ®); + reg &= ~0xf; + reg |= APS_OFF; + pmic_reg_write(p, PFUZE100_SW3AMODE, reg); + + return 0; +} +#endif + +void spl_board_init(void) +{ + /* Serial download mode */ + if (is_usb_boot()) { + puts("Back to ROM, SDP\n"); + restore_boot_params(); + } + + puts("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + + init_uart_clk(0); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_init(); + if (ret) { + debug("spl_init() failed: %d\n", ret); + hang(); + } + + enable_tzc380(); + + /* Adjust pmic voltage to 1.0V for 800M */ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + + power_init_board(); + + /* DDR initialization */ + spl_dram_init(); + + board_init_r(NULL, 0); +} diff --git a/cmd/fuse.c b/cmd/fuse.c index 42d74fa8837a..f1626a27bb2e 100644 --- a/cmd/fuse.c +++ b/cmd/fuse.c @@ -62,14 +62,19 @@ static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) printf("Reading bank %u:\n", bank); for (i = 0; i < cnt; i++, word++) { + char name[16]; + char vbuf[16]; if (!(i % 4)) - printf("\nWord 0x%.8x:", word); + printf("\nWord 0x%.8x: ", word); ret = fuse_read(bank, word, &val); if (ret) goto err; - printf(" %.8x", val); + snprintf(name, sizeof(name), "fuse_read_val%x", i); + snprintf(vbuf, sizeof(vbuf), "%.8x", val); + env_set(name, vbuf); + puts(vbuf); } putc('\n'); } else if (!strcmp(op, "sense")) { diff --git a/cmd/i2c.c b/cmd/i2c.c index 56df8eb3bca5..738d68603e0a 100644 --- a/cmd/i2c.c +++ b/cmd/i2c.c @@ -1823,11 +1823,9 @@ static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, printf("Current bus is %d\n", bus_no); } else { bus_no = simple_strtoul(argv[1], NULL, 10); -#if defined(CONFIG_SYS_I2C) - if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) { - printf("Invalid bus %d\n", bus_no); +#ifndef CONFIG_DM_I2C + if (!i2c_get_adapter(bus_no)) return -1; - } #endif printf("Setting bus to %d\n", bus_no); #ifdef CONFIG_DM_I2C diff --git a/common/usb_hub.c b/common/usb_hub.c index e1d93b833358..4b1e899a2946 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -196,7 +196,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub) * Do a minimum delay of the larger value of 100ms or pgood_delay * so that the power can stablize before the devices are queried */ - hub->query_delay = get_timer(0) + max(100, (int)pgood_delay); + hub->query_delay = max(100, (int)pgood_delay); /* * Record the power-on timeout here. The max. delay (timeout) @@ -427,7 +427,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port) return ret; } -static int usb_scan_port(struct usb_device_scan *usb_scan) +static int usb_scan_port(struct usb_device_scan *usb_scan, unsigned long start) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; @@ -445,21 +445,13 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) * Don't talk to the device before the query delay is expired. * This is needed for voltages to stabalize. */ - if (get_timer(0) < hub->query_delay) + if (get_timer(start) < hub->query_delay) return 0; ret = usb_get_port_status(dev, i + 1, portsts); if (ret < 0) { debug("get_port_status failed\n"); - if (get_timer(0) >= hub->connect_timeout) { - debug("devnum=%d port=%d: timeout\n", - dev->devnum, i + 1); - /* Remove this device from scanning list */ - list_del(&usb_scan->list); - free(usb_scan); - return 0; - } - return 0; + goto check_timeout; } portstatus = le16_to_cpu(portsts->wPortStatus); @@ -474,17 +466,8 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) * in the PORTSC register of a root hub), ignore such case. */ if (!(portchange & USB_PORT_STAT_C_CONNECTION) && - !(portstatus & USB_PORT_STAT_CONNECTION)) { - if (get_timer(0) >= hub->connect_timeout) { - debug("devnum=%d port=%d: timeout\n", - dev->devnum, i + 1); - /* Remove this device from scanning list */ - list_del(&usb_scan->list); - free(usb_scan); - return 0; - } - return 0; - } + !(portstatus & USB_PORT_STAT_CONNECTION)) + goto check_timeout; if (portchange & USB_PORT_STAT_C_RESET) { debug("port %d reset change\n", i + 1); @@ -558,6 +541,16 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) list_del(&usb_scan->list); free(usb_scan); + return 0; +check_timeout: + if (get_timer(start) >= hub->connect_timeout) { + debug("devnum=%d port=%d: timeout\n", + dev->devnum, i + 1); + /* Remove this device from scanning list */ + list_del(&usb_scan->list); + free(usb_scan); + return 0; + } return 0; } @@ -567,6 +560,7 @@ static int usb_device_list_scan(void) struct usb_device_scan *tmp; static int running; int ret = 0; + unsigned long start; /* Only run this loop once for each controller */ if (running) @@ -574,16 +568,18 @@ static int usb_device_list_scan(void) running = 1; + start = get_timer(0); while (1) { /* We're done, once the list is empty again */ if (list_empty(&usb_scan_list)) goto out; + mdelay(1); list_for_each_entry_safe(usb_scan, tmp, &usb_scan_list, list) { int ret; /* Scan this port */ - ret = usb_scan_port(usb_scan); + ret = usb_scan_port(usb_scan, start); if (ret) goto out; } diff --git a/configs/imx8mq_hb_defconfig b/configs/imx8mq_hb_defconfig new file mode 100644 index 000000000000..070f66371031 --- /dev/null +++ b/configs/imx8mq_hb_defconfig @@ -0,0 +1,82 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_SYS_TEXT_BASE=0x40200000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_TARGET_IMX8MQ_HB=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 +CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8mq-hb" +CONFIG_OF_LIST="fsl-imx8mq-hb" +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage.cfg" +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" +CONFIG_OF_BOARD_SETUP=y +CONFIG_SUPPORT_RAW_INITRD=y +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DISTRO_DEFAULTS=y +#CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" +CONFIG_SPL=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MMC_RPMB=y +CONFIG_CMD_PART=y +CONFIG_CMD_PING=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_FS_UUID=y +CONFIG_CMD_USB=y +CONFIG_DOS_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=128 +CONFIG_EFI_PARTITION_ENTRIES_OFF=0 +CONFIG_PARTITION_UUIDS=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_OF_CONTROL=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_MMC=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX8M=y +CONFIG_SYS_I2C_MXC=y +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PFUZE100=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_THERMAL=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_FSL_ESDHC=y +CONFIG_MXC_UART=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_HOST=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +# CONFIG_USB_XHCI_DWC3_OF_SIMPLE is not set +# CONFIG_USB_XHCI_PCI is not set +# CONFIG_USB_XHCI_FSL is not set +CONFIG_USB_XHCI_IMX8M=y +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_DWC3 is not set +CONFIG_USB_STORAGE=y diff --git a/configs/mvebu_cex-88f8040_defconfig b/configs/mvebu_cex-88f8040_defconfig new file mode 100644 index 000000000000..8413671b3952 --- /dev/null +++ b/configs/mvebu_cex-88f8040_defconfig @@ -0,0 +1,75 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x00000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_MVEBU_ARMADA_8K=y +CONFIG_DEBUG_UART_BASE=0xf0512000 +CONFIG_DEBUG_UART_CLOCK=200000000 +CONFIG_SMBIOS_PRODUCT_NAME="" +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=2 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_ARCH_EARLY_INIT_R=y +CONFIG_BOARD_EARLY_INIT_F=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_MVEBU_BUBT=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MAC_PARTITION=y +CONFIG_DEFAULT_DEVICE_TREE="armada-8040-cex" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_AHCI_MVEBU=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHYLIB=y +CONFIG_PHY_GIGE=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MVEBU=y +CONFIG_MVEBU_COMPHY_SUPPORT=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_8K=y +CONFIG_DM_REGULATOR_FIXED=y +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_KIRKWOOD_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_SMBIOS_MANUFACTURER="" diff --git a/drivers/core/devres.c b/drivers/core/devres.c index f2a19ec61b19..6c429c89cc95 100644 --- a/drivers/core/devres.c +++ b/drivers/core/devres.c @@ -240,6 +240,10 @@ void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp) { void *data; + if (!dev) { + debug("%s: dev=%p\n", __func__, dev); + return kmalloc(size, gfp); + } data = _devres_alloc(devm_kmalloc_release, size, gfp); if (unlikely(!data)) return NULL; diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c index 234277a299c7..cf0d76718597 100644 --- a/drivers/i2c/i2c_core.c +++ b/drivers/i2c/i2c_core.c @@ -10,25 +10,42 @@ #include #include -struct i2c_adapter *i2c_get_adapter(int index) +struct i2c_adapter *i2c_get_adapter(int bus) { - struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter, - i2c); - int max = ll_entry_count(struct i2c_adapter, i2c); - int i; + struct i2c_adapter *i2cp = ll_entry_start(struct i2c_adapter, i2c); - if (index >= max) { - printf("Error, wrong i2c adapter %d max %d possible\n", - index, max); - return i2c_adap_p; + bus = I2C_ADAPTER(bus); +#ifndef CONFIG_SYS_I2C_DIRECT_BUS + if (bus >= CONFIG_SYS_NUM_I2C_BUSES) { + printf("Invalid bus %d, max is %d\n", bus, + CONFIG_SYS_NUM_I2C_BUSES - 1); + return NULL; } - if (index == 0) - return i2c_adap_p; +#endif - for (i = 0; i < index; i++) - i2c_adap_p++; +#ifdef CONFIG_SYS_I2C_MASK + if (!(BIT(bus) & CONFIG_SYS_I2C_MASK)) { + printf("Invalid bus %d\n", bus); + return NULL; + } +#else + { + int max = ll_entry_count(struct i2c_adapter, i2c); + if (bus >= max) { + printf("Error, wrong i2c adapter %d max %d possible\n", + bus, max); + return NULL; + } + } +#endif + return i2cp + bus; +} - return i2c_adap_p; +struct i2c_adapter *i2c_get_adapter_valid(int bus) +{ + struct i2c_adapter *i2cp = i2c_get_adapter(bus); + + return i2cp ? i2cp : ll_entry_start(struct i2c_adapter, i2c); } #if !defined(CONFIG_SYS_I2C_DIRECT_BUS) @@ -235,22 +252,11 @@ unsigned int i2c_get_bus_num(void) */ int i2c_set_bus_num(unsigned int bus) { - int max; - if ((bus == I2C_BUS) && (I2C_ADAP->init_done > 0)) return 0; -#ifndef CONFIG_SYS_I2C_DIRECT_BUS - if (bus >= CONFIG_SYS_NUM_I2C_BUSES) + if (!i2c_get_adapter(bus)) return -1; -#endif - - max = ll_entry_count(struct i2c_adapter, i2c); - if (I2C_ADAPTER(bus) >= max) { - printf("Error, wrong i2c adapter %d max %d possible\n", - I2C_ADAPTER(bus), max); - return -2; - } #ifndef CONFIG_SYS_I2C_DIRECT_BUS i2c_mux_disconnect_all(); diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 74007e2ad43f..655c2d7504fd 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -146,7 +146,9 @@ struct fsl_esdhc_priv { #ifdef CONFIG_DM_GPIO struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; + struct gpio_desc reset_gpio; #endif + int sysctrl_inita_needed; }; /* Return the XFERTYP flags for a given command and data packet */ @@ -420,6 +422,18 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, * resolve timing issues with some cards */ udelay(1000); + if (priv->sysctrl_inita_needed) { + unsigned long start; + + /* send 80 clocks before 1st command */ + priv->sysctrl_inita_needed = 0; + esdhc_setbits32(®s->sysctl, SYSCTL_INITA); + start = get_timer(0); + while (esdhc_read32(®s->sysctl) & SYSCTL_INITA) { + if (get_timer(start) >= 10) + break; + } + } /* Set up for a data transfer if we have one */ if (data) { @@ -980,7 +994,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) /* Reset the entire host controller */ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); - + priv->sysctrl_inita_needed = 1; /* Wait until the controller is available */ start = get_timer(0); while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { @@ -1128,6 +1142,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, regs = priv->esdhc_regs; /* First reset the eSDHC controller */ + priv->sysctrl_inita_needed = 1; ret = esdhc_reset(regs); if (ret) return ret; @@ -1449,6 +1464,8 @@ static int fsl_esdhc_probe(struct udevice *dev) GPIOD_IS_IN); if (ret) priv->wp_enable = 0; + gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio, + GPIOD_IS_OUT_ACTIVE); #endif priv->vs18_enable = 0; @@ -1520,6 +1537,12 @@ static int fsl_esdhc_probe(struct udevice *dev) } } +#ifdef CONFIG_DM_GPIO + if (dm_gpio_is_valid(&priv->reset_gpio)) { + udelay(500); + dm_gpio_set_value(&priv->reset_gpio, 0); /* release reset */ + } +#endif ret = fsl_esdhc_init(priv, plat); if (ret) { dev_err(dev, "fsl_esdhc_init failure\n"); diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c index ad0a0c815014..a3682115ee9d 100644 --- a/drivers/mtd/spi/spi_flash_ids.c +++ b/drivers/mtd/spi/spi_flash_ids.c @@ -107,6 +107,7 @@ const struct spi_flash_info spi_flash_ids[] = { {"s25fl128p_64k", INFO(0x012018, 0x0301, 64 * 1024, 256, RD_FULL | WR_QPP) }, {"s25fl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, RD_FULL | WR_QPP) }, {"s25fl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, RD_FULL | WR_QPP) }, + {"s25fl064l", INFO(0x016017, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP | SECT_4K) }, {"s25fl128s_256k", INFO(0x012018, 0x4d00, 256 * 1024, 64, RD_FULL | WR_QPP) }, {"s25fl128s_64k", INFO(0x012018, 0x4d01, 64 * 1024, 256, RD_FULL | WR_QPP) }, {"s25fl128l", INFO(0x016018, 0, 64 * 1024, 256, RD_FULL | WR_QPP) }, diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e837eb7688cc..6edd0aab0af2 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -797,7 +797,7 @@ int phy_reset(struct phy_device *phydev) } #endif - if (phy_write(phydev, devad, MII_BMCR, BMCR_RESET) < 0) { + if (phy_write(phydev, devad, MII_BMCR, BMCR_RESET|BMCR_ANENABLE) < 0) { debug("PHY reset failed\n"); return -1; } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 597db4b9cbba..ed3943ce2918 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -522,7 +522,7 @@ config MVEBU_A3700_UART config MXC_UART bool "IMX serial port support" - depends on MX5 || MX6 + depends on MX5 || MX6 || MX7 || IMX8M help If you have a machine based on a Motorola IMX CPU you can enable its onboard serial port by enabling this option. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1ab5cee60969..c10d1264ceb3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -396,6 +396,25 @@ static void dwc3_phy_setup(struct dwc3 *dwc) mdelay(100); } +void dwc3_set_suspend_clk(struct dwc3 *dwc) +{ + u32 reg; + + /* + * 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. + */ + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~(DWC3_GCTL_PWRDNSCALE(0x1fff)); + reg |= DWC3_GCTL_PWRDNSCALE(dwc->power_down_scale); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -444,6 +463,9 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err0; + if (dwc->power_down_scale) + dwc3_set_suspend_clk(dwc); + reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; @@ -674,6 +696,8 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev) if (dwc3_dev->tx_de_emphasis) tx_de_emphasis = dwc3_dev->tx_de_emphasis; + dwc->power_down_scale = dwc3_dev->power_down_scale; + /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 58fe91dc5131..ba70ecf14740 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -642,6 +642,7 @@ struct dwc3_scratchpad_array { * @dr_mode: requested mode of operation * @dcfg: saved contents of DCFG register * @gctl: saved contents of GCTL register + * @power_down_scale: 16KHz clock periods for suspend_clk * @isoch_delay: wValue from Set Isochronous Delay request; * @u2sel: parameter from Set SEL request. * @u2pel: parameter from Set SEL request. @@ -766,6 +767,7 @@ struct dwc3 { enum dwc3_ep0_state ep0state; enum dwc3_link_state link_state; + u16 power_down_scale; u16 isoch_delay; u16 u2sel; u16 u2pel; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a213c918bcf8..985da93d96c3 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -94,6 +94,14 @@ config USB_XHCI_FSL depends on !SPL_NO_USB help Enables support for the on-chip xHCI controller on NXP Layerscape SoCs. + +config USB_XHCI_IMX8M + bool "XHCI support for imx8M(mscale)" + depends on ARCH_IMX8M + default y + help + Enables support for the on-chip xHCI controller on imx8m(mscale) SoC. + endif # USB_XHCI_HCD config USB_EHCI_HCD diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index cb8c315a1510..1f3b7c9a645c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o obj-$(CONFIG_USB_XHCI_RCAR) += xhci-rcar.o obj-$(CONFIG_USB_XHCI_STI) += dwc3-sti-glue.o +obj-$(CONFIG_USB_XHCI_IMX8M) += xhci-imx8m.o # designware obj-$(CONFIG_USB_DWC2) += dwc2.o diff --git a/drivers/usb/host/xhci-imx8m.c b/drivers/usb/host/xhci-imx8m.c new file mode 100644 index 000000000000..62c88ee62058 --- /dev/null +++ b/drivers/usb/host/xhci-imx8m.c @@ -0,0 +1,262 @@ +/* + * Copyright 2017 NXP + * + * FSL i.MX8M USB HOST xHCI Controller + * + * Author: Jun Li + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "xhci.h" +#include + +/* Declare global data pointer */ +DECLARE_GLOBAL_DATA_PTR; + +#define USBMIX_PHY_OFFSET 0xF0040 + +#define PHY_CTRL0_REF_SSP_EN BIT(2) + +#define PHY_CTRL1_RESET BIT(0) +#define PHY_CTRL1_ATERESET BIT(3) +#define PHY_CTRL1_VDATSRCENB0 BIT(19) +#define PHY_CTRL1_VDATDETENB0 BIT(20) + +#define PHY_CTRL2_TXENABLEN0 BIT(8) + +struct imx8m_usbmix { + u32 phy_ctrl0; + u32 phy_ctrl1; + u32 phy_ctrl2; + u32 phy_ctrl3; +}; + +struct imx8m_xhci { + struct xhci_hccr *hcd; + struct dwc3 *dwc3_reg; + struct imx8m_usbmix *usbmix_reg; +}; + +struct imx8m_usbctrl_data { + u32 usb_id; + unsigned long ctr_addr; +}; + + +#ifdef CONFIG_DM_USB +struct xhci_imx8m_priv { + struct xhci_ctrl xhci; + struct clk_bulk clks; +#ifdef CONFIG_DM_GPIO + struct gpio_desc reset_gpio; +#endif +}; +#else +static struct imx8m_usbctrl_data ctr_data[] = { + {0, USB1_BASE_ADDR}, + {1, USB2_BASE_ADDR}, +}; +#endif + +static void imx8m_usb_phy_init(struct imx8m_usbmix *usbmix_reg) +{ + u32 reg; + + reg = readl(&usbmix_reg->phy_ctrl1); + reg &= ~(PHY_CTRL1_VDATSRCENB0 | PHY_CTRL1_VDATDETENB0); + reg |= PHY_CTRL1_RESET | PHY_CTRL1_ATERESET; + writel(reg, &usbmix_reg->phy_ctrl1); + + reg = readl(&usbmix_reg->phy_ctrl0); + reg |= PHY_CTRL0_REF_SSP_EN; + writel(reg, &usbmix_reg->phy_ctrl0); + + reg = readl(&usbmix_reg->phy_ctrl2); + reg |= PHY_CTRL2_TXENABLEN0; + writel(reg, &usbmix_reg->phy_ctrl2); + + reg = readl(&usbmix_reg->phy_ctrl1); + reg &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET); + writel(reg, &usbmix_reg->phy_ctrl1); +} + +static void imx8m_xhci_set_suspend_clk(struct dwc3 *dwc3_reg) +{ + u32 reg; + + /* Set suspend_clk to be 32KHz */ + reg = readl(&dwc3_reg->g_ctl); + reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK); + reg |= DWC3_GCTL_PWRDNSCALE(2); + + writel(reg, &dwc3_reg->g_ctl); +} + +static int imx8m_xhci_core_init(struct imx8m_xhci *imx8m_xhci) +{ + int ret = 0; + + imx8m_usb_phy_init(imx8m_xhci->usbmix_reg); + + ret = dwc3_core_init(imx8m_xhci->dwc3_reg); + if (ret) { + debug("%s:failed to initialize core\n", __func__); + return ret; + } + + imx8m_xhci_set_suspend_clk(imx8m_xhci->dwc3_reg); + + /* We are hard-coding DWC3 core to Host Mode */ + dwc3_set_mode(imx8m_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST); + + /* Set GFLADJ_30MHZ as 20h as per XHCI spec default value */ + dwc3_set_fladj(imx8m_xhci->dwc3_reg, GFLADJ_30MHZ_DEFAULT); + + return ret; +} + +int imx8m_usb_common_init(void *base, struct xhci_hccr **hccr, struct xhci_hcor **hcor) +{ + int ret; + struct imx8m_xhci ctx; + + ctx.hcd = (struct xhci_hccr *)base; + ctx.dwc3_reg = (struct dwc3 *)(base + DWC3_REG_OFFSET); + ctx.usbmix_reg = (struct imx8m_usbmix *)(base + USBMIX_PHY_OFFSET); + + ret = imx8m_xhci_core_init(&ctx); + if (ret < 0) { + puts("Failed to initialize imx8m xhci\n"); + return ret; + } + + *hccr = (struct xhci_hccr *)ctx.hcd; + *hcor = (struct xhci_hcor *)((uintptr_t) *hccr + + HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); + + debug("imx8m-xhci: init hccr %lx and hcor %lx hc_length %lx\n", + (uintptr_t)*hccr, (uintptr_t)*hcor, + (uintptr_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase))); + + return ret; +} + +#ifdef CONFIG_DM_USB +static int imx8_of_clk_init(struct udevice *dev, + struct xhci_imx8m_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS) + return 0; + if (ret) + return ret; + +#if CONFIG_IS_ENABLED(CLK) + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } +#endif + + return 0; +} + +#ifdef CONFIG_DM_GPIO +static void imx8_of_reset_gpio_init(struct udevice *dev, + struct xhci_imx8m_priv *priv) +{ + gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (dm_gpio_is_valid(&priv->reset_gpio)) { + udelay(500); + /* release reset */ + dm_gpio_set_value(&priv->reset_gpio, 0); + } +} +#else +static void imx8_of_reset_gpio_init(struct udevice *dev, + struct xhci_imx8m_priv *priv) +{ +} +#endif + +static int imx8m_xhci_probe(struct udevice *dev) +{ + struct xhci_imx8m_priv *priv = dev_get_priv(dev); + struct xhci_hccr *hccr; + struct xhci_hcor *hcor; + fdt_addr_t hcd_base; + + int ret = 0; + + /* + * Get the base address for XHCI controller from the device node + */ + hcd_base = devfdt_get_addr(dev); + if (hcd_base == FDT_ADDR_T_NONE) { + printf("Can't get the XHCI register base address\n"); + return -ENXIO; + } + imx8m_usb_power(hcd_base == USB1_BASE_ADDR ? 0 : 1, true); + + imx8_of_clk_init(dev, priv); + imx8_of_reset_gpio_init(dev, priv); + ret = imx8m_usb_common_init((void *)hcd_base, &hccr, &hcor); + if (ret < 0) + return ret; + + return xhci_register(dev, hccr, hcor); +} + +static int imx8m_xhci_remove(struct udevice *dev) +{ + return xhci_deregister(dev); +} + +static const struct udevice_id xhci_usb_ids[] = { + { .compatible = "fsl,imx8mq-dwc3", }, + { } +}; + +U_BOOT_DRIVER(imx8m_xhci) = { + .name = "imx8m_xhci", + .id = UCLASS_USB, + .of_match = xhci_usb_ids, + .probe = imx8m_xhci_probe, + .remove = imx8m_xhci_remove, + .ops = &xhci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct xhci_imx8m_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#else +int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) +{ + int ret = 0; + + ret = board_usb_init(ctr_data[index].usb_id, USB_INIT_HOST); + if (ret != 0) { + imx8m_usb_power(ctr_data[index].usb_id, false); + puts("Failed to initialize board for imx8m USB\n"); + return ret; + } + return imx8m_usb_common_init((void*)ctr_data[index].ctr_addr, hccr, hcor); +} + +void xhci_hcd_stop(int index) +{ + board_usb_cleanup(ctr_data[index].usb_id, USB_INIT_HOST); +} +#endif diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 25c94f4a9e36..6e536bbf5fe2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -552,6 +552,29 @@ config VIDEO_IPUV3 This enables framebuffer driver for i.MX processors working on the IPUv3(Image Processing Unit) internal graphic processor. +config VIDEO_IMXDCSS + bool "i.MX8 DCSS display support" + default n + depends on VIDEO && IMX8M + help + Support for DCSS display controller for i.MX8 processors. + +config VIDEO_IMX_HDP_LOAD + bool "i.MX8 HDMI/DP firmware loading" + default n + depends on VIDEO && MX8QM + help + Support for HDMI/DP firmware loading for i.MX8QM processors. The + firmware is copied from system memory to the HDMI/DP IRAM and + DRAM memory. + +config VIDEO_IMX8_HDMI + bool "i.MX8 HDMI Splash screen" + default n + depends on VIDEO && IMX8M + help + Support for HDMI i.MX8 processors. + config CFB_CONSOLE bool "Enable colour frame buffer console" depends on VIDEO diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 80e1e829033a..98eabd9863c1 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -63,4 +63,5 @@ obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa.o obj-y += bridge/ +obj-y += imx/ obj-y += sunxi/ diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 636c3e8c184d..4ffb92a21796 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -1176,7 +1176,7 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, y = __le32_to_cpu(img->header.height) - 1; ncolors = __le32_to_cpu(img->header.colors_used); bpp = VIDEO_PIXEL_SIZE; - fbp = (unsigned char *) ((unsigned int) video_fb_address + + fbp = (unsigned char *) ((unsigned long) video_fb_address + (y + yoff) * VIDEO_LINE_LEN + xoff * bpp); @@ -1231,7 +1231,7 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, x = 0; y--; fbp = (unsigned char *) - ((unsigned int) video_fb_address + + ((unsigned long) video_fb_address + (y + yoff) * VIDEO_LINE_LEN + xoff * bpp); continue; @@ -1244,7 +1244,7 @@ static int display_rle8_bitmap(struct bmp_image *img, int xoff, int yoff, x += bm[2]; y -= bm[3]; fbp = (unsigned char *) - ((unsigned int) video_fb_address + + ((unsigned long) video_fb_address + (y + yoff) * VIDEO_LINE_LEN + xoff * bpp); bm += 4; @@ -2023,7 +2023,7 @@ static int cfg_video_init(void) if (pGD == NULL) return -1; - video_fb_address = (void *) VIDEO_FB_ADRS; + video_fb_address = (void *)(unsigned long) VIDEO_FB_ADRS; cfb_do_flush_cache = cfb_fb_is_in_dram() && dcache_status(); diff --git a/drivers/video/imx/Makefile b/drivers/video/imx/Makefile new file mode 100644 index 000000000000..5c243af8fde6 --- /dev/null +++ b/drivers/video/imx/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2017-2018 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +UBOOTINCLUDE += -I$(srctree)/drivers/video/imx/hdp +obj-$(CONFIG_VIDEO_IMX_HDP_LOAD) += hdp_load.o hdp/ +obj-$(CONFIG_VIDEO_IMX8_HDMI) += hdp.o imx8_hdmi.o hdp/ diff --git a/drivers/video/imx/hdp.c b/drivers/video/imx/hdp.c new file mode 100644 index 000000000000..2f946ed2872b --- /dev/null +++ b/drivers/video/imx/hdp.c @@ -0,0 +1,46 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int do_hdp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (argc < 2) + return 0; + + if (strncmp(argv[1], "colorbar", 8) == 0) { + GraphicDevice *gdev; + struct video_mode_settings *vm; + + gdev = imx8m_get_gd(); + vm = imx8m_get_gmode(); + imx8m_show_gmode(); + + imx8m_create_color_bar( + (void *)((uint64_t)gdev->frameAdrs), + vm); + printf("colorbar test\n"); + } else if (strncmp(argv[1], "stop", 4) == 0) { + imx8_hdmi_disable(); + printf("stopping hdmi\n"); + } else { + printf("test error argc %d\n", argc); + } + + return 0; +} +/***************************************************/ + +U_BOOT_CMD( + hdp, CONFIG_SYS_MAXARGS, 1, do_hdp, + "hdmi/dp display test commands", + "[] ...\n" + "colorbar - display a colorbar pattern\n" + ); diff --git a/drivers/video/imx/hdp/API_AFE.c b/drivers/video/imx/hdp/API_AFE.c new file mode 100644 index 000000000000..7b778cd3d586 --- /dev/null +++ b/drivers/video/imx/hdp/API_AFE.c @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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.c + * + ****************************************************************************** + */ + +#include "address.h" +#include "API_AFE.h" +#include "util.h" +#ifndef __UBOOT__ +#include +#endif + +void afe_write(unsigned int offset, unsigned short val) +{ +#ifdef EXTERNAL_AFE + cdn_phapb_write(offset << 2, val); +#else + CDN_API_STATUS sts; + + sts = cdn_api_general_write_register_blocking( + ADDR_AFE + (offset << 2), val); + + if (sts != CDN_OK) { + printf("CDN_API_General_Write_Register_blocking(0x%.8X, 0x%.8X) returned %d\n", + offset, + val, + (int)sts); + } +#endif +} + +unsigned short afe_read(unsigned int offset) +{ + GENERAL_READ_REGISTER_RESPONSE resp; + +#ifdef EXTERNAL_AFE + cdn_phapb_read(offset << 2, &resp.val); +#else + CDN_API_STATUS sts; + + sts = cdn_api_general_read_register_blocking( + ADDR_AFE + (offset << 2), &resp); + + if (sts != CDN_OK) { + printf("CDN_API_General_Read_Register_blocking(0x%.8X) returned %d\n", + offset, + (int)sts); + } +#endif + 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; + printf("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; +} diff --git a/drivers/video/imx/hdp/API_AFE.h b/drivers/video/imx/hdp/API_AFE.h new file mode 100644 index 000000000000..f3db97368380 --- /dev/null +++ b/drivers/video/imx/hdp/API_AFE.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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.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; +} reg_field_t; + +unsigned char AFE_check_rate_supported(ENUM_AFE_LINK_RATE rate); +void afe_write(unsigned int offset, unsigned short val); +unsigned short afe_read(unsigned int offset); +void AFE_init(int num_lanes, ENUM_AFE_LINK_RATE link_rate); +void AFE_power(int num_lanes, ENUM_AFE_LINK_RATE link_rate); + +/*extern int cdn_phapb_read(unsigned int addr, unsigned int *value);*/ +/*extern int cdn_phapb_write(unsigned int addr, unsigned int value);*/ +void set_field_value(reg_field_t *reg_field, u32 value); +int set_reg_value(reg_field_t reg_field); + +#endif diff --git a/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.c b/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.c new file mode 100644 index 000000000000..933ecfa8d438 --- /dev/null +++ b/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.c @@ -0,0 +1,1863 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_t28hpc_hdmitx.c + * + ****************************************************************************** + */ + +#include "API_AFE_t28hpc_hdmitx.h" +#include "API_AFE.h" +#include "externs.h" + +#ifndef DEBUG +static inline void write16(uint32_t addr, uint16_t val) +{ + afe_write(addr, val); +} + +static inline uint16_t read16(uint32_t addr) +{ + return afe_read(addr); +} +#else +#define write16(addr, val) __write16(addr, val, __LINE__) +static inline void __write16(uint32_t addr, uint16_t val, int line) +{ + afe_write(addr, val); + debug("write16():%4d Writting value 0x%04X at address 0x%05X (0x%04X)\n", + line, val, (0x20000 * 4) + (addr << 2), addr); +} +#define read16(addr) __read16(addr, __LINE__) +static inline uint16_t __read16(uint32_t addr, int line) +{ + debug("read16():%5d Reading from address 0x%05X (0x%04X)\n", + line, (0x20000 * 4) + (addr << 2), addr); + return afe_read(addr); +} + +#endif + +static char inside(u32 value, u32 left_sharp_corner, + u32 right_sharp_corner) +{ + if (value < left_sharp_corner) + return false; + if (value > right_sharp_corner) + return false; + return true; +} + +void aux_cfg_t28hpc(void) +{ + write16(0x5025, 0x0001); + + write16(0x5024, 36); + + write16(0x5021, 0x0100); + write16(0x5021, 0x0300); + write16(0x5026, 0x0000); + write16(0x5020, 0x2008); + write16(0x5020, 0x2018); + write16(0x5020, 0xA018); + write16(0x5021, 0x030C); + write16(0x5029, 0x0000); + write16(0x5027, 0x4001); + write16(0x5020, 0xA098); + write16(0x5020, 0xA198); + write16(0x5021, 0x030D); + write16(0x5021, 0x030F); +} + +int phy_cfg_t28hpc(int num_lanes, VIC_MODES vic_mode, int bpp, + VIC_PXL_ENCODING_FORMAT format, bool pixel_clk_from_phy) +{ + const int phy_reset_workaround = 1; + unsigned int vco_freq; + unsigned char k; + uint32_t reg_val; + uint32_t pixel_freq_khz = vic_table[vic_mode][PIXEL_FREQ_KHZ]; + uint32_t character_clock_ratio_num = 1; + uint32_t character_clock_ratio_den = 1; + uint32_t character_freq_khz; + const unsigned int refclk_freq_khz = 27000; + unsigned int ftemp, ftemp2; + + clk_ratio_t clk_ratio = 0; + 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 pll_feedback_divider_total; + 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; + + cmnda_pll0_fb_div_high.value = 0x00A; + ftemp = pixel_freq_khz; + + debug(" VIC %d, pixel clock %u kHz\n", vic_mode, ftemp); + + /* 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; + pll_feedback_divider_total.msb = 9; + pll_feedback_divider_total.lsb = 0; + 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; + + if (phy_reset_workaround) { + /* register PHY_PMA_ISOLATION_CTRL */ + write16(0xC81F, 0xD000); /* enable PHY iso mode only for CMN */ + /* register PHY_PMA_ISO_PLL_CTRL1 */ + reg_val = read16(0xC812); + reg_val &= 0xFF00; + reg_val |= 0x0012; + /* set pll0_clk_datart1_div/pll0_clk_datart0_div dividers */ + write16(0xC812, reg_val); + /* register PHY_ISO_CMN_CTRL */ + /* assert PHY reset from isolation register */ + write16(0xC010, 0x0000); + /* register PHY_PMA_ISO_CMN_CTRL */ + write16(0xC810, 0x0000); /* assert PMA CMN reset */ + /* register XCVR_DIAG_BIDI_CTRL */ + for (k = 0; k < num_lanes; k++) + write16(0x40E8 | (k << 9), 0x00FF); + } + /*--------------------------------------------------------------- + * Describing Task phy_cfg_hdp + * --------------------------------------------------------------*/ + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = read16(0xC800); + reg_val &= 0xFFF7; + reg_val |= 0x0008; + write16(0xC800, reg_val); + + /* register CMN_DIAG_PLL0_TEST_MODE */ + write16(0x01C4, 0x0020); + /* register CMN_PSM_CLK_CTRL */ + write16(0x0061, 0x0016); + + 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: + debug("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; + } + } + + character_freq_khz = pixel_freq_khz * + character_clock_ratio_num / character_clock_ratio_den; + ftemp = pixel_freq_khz; + ftemp2 = character_freq_khz; + debug("Pixel clock frequency: %u kHz, character clock frequency: %u, color depth is %0d-bit.\n", + ftemp, ftemp2, bpp); + if (pixel_clk_from_phy == 0) { + /* ----------------------------------------------------------- + * Describing Task phy_cfg_hdmi_pll0_0pt5736 (Clock is input) + * -----------------------------------------------------------*/ + + /* register CMN_PLL0_VCOCAL_INIT_TMR */ + write16(0x0084, 0x0064); + /* register CMN_PLL0_VCOCAL_ITER_TMR */ + write16(0x0085, 0x000A); + /* register PHY_HDP_CLK_CTL */ + reg_val = read16(0xC009); + reg_val &= 0x00FF; + reg_val |= 0x1200; + write16(0xC009, reg_val); + + switch (clk_ratio) { + case CLK_RATIO_1_1: + if (inside(pixel_freq_khz, 340000, 600000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x3C); + set_field_value(&cmnda_pll0_fb_div_low, 0x24A); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x06); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 600); + } else if (inside(pixel_freq_khz, 170000, 340000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x22); + set_field_value(&cmnda_pll0_fb_div_low, 0x146); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x07); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 340); + } else if (inside(pixel_freq_khz, 85000, 170000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + set_field_value(&cmnda_pll0_ip_div, 0x11); + set_field_value(&cmnda_pll0_fb_div_low, 0x146); + set_field_value(&cmn_ref_clk_dig_div, 0x00); + set_field_value(÷r_scaler, 0x07); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 340); + } else if (inside(pixel_freq_khz, 42500, 85000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + set_field_value(&cmnda_pll0_ip_div, 0x08); + set_field_value(&cmnda_pll0_fb_div_low, 0x132); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 320); + } else if (inside(pixel_freq_khz, 25000, 42500)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + set_field_value(&cmnda_pll0_ip_div, 0x05); + set_field_value(&cmnda_pll0_fb_div_low, 0x182); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 400); + } else { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } + break; + + case CLK_RATIO_5_4: + if (inside(pixel_freq_khz, 272000, 480000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x30); + set_field_value(&cmnda_pll0_fb_div_low, 0x24A); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x05); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 600); + } else if (inside(pixel_freq_khz, 136000, 272000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x1A); + set_field_value(&cmnda_pll0_fb_div_low, 0x137); + set_field_value(&cmn_ref_clk_dig_div, 0x02); + set_field_value(÷r_scaler, 0x04); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 325); + } else if (inside(pixel_freq_khz, 68000, 136000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + set_field_value(&cmnda_pll0_ip_div, 0x0D); + set_field_value(&cmnda_pll0_fb_div_low, 0x137); + set_field_value(&cmn_ref_clk_dig_div, 0x02); + set_field_value(÷r_scaler, 0x02); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 325); + } else if (inside(pixel_freq_khz, 34000, 68000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + set_field_value(&cmnda_pll0_ip_div, 0x06); + set_field_value(&cmnda_pll0_fb_div_low, 0x11E); + set_field_value(&cmn_ref_clk_dig_div, 0x02); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 300); + } else if (inside(pixel_freq_khz, 25000, 34000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmnda_pll0_fb_div_low, 0x182); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 400); + } else { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } + break; + case CLK_RATIO_3_2: + if (inside(pixel_freq_khz, 226000, 400000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x28); + set_field_value(&cmnda_pll0_fb_div_low, 0x24A); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x04); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 600); + } else if (inside(pixel_freq_khz, 113000, 226000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x16); + set_field_value(&cmnda_pll0_fb_div_low, 0x13C); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x05); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 330); + } else if (inside(pixel_freq_khz, 56000, 113000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + set_field_value(&cmnda_pll0_ip_div, 0x0B); + set_field_value(&cmnda_pll0_fb_div_low, 0x13C); + set_field_value(&cmn_ref_clk_dig_div, 0x00); + set_field_value(÷r_scaler, 0x05); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 330); + } else if (inside(pixel_freq_khz, 28000, 56000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + set_field_value(&cmnda_pll0_ip_div, 0x06); + set_field_value(&cmnda_pll0_fb_div_low, 0x15A); + set_field_value(&cmn_ref_clk_dig_div, 0x02); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 360); + } else if (inside(pixel_freq_khz, 25000, 28000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmnda_pll0_fb_div_low, 0x15A); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 360); + } else { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } + break; + case CLK_RATIO_2_1: + if (inside(pixel_freq_khz, 170000, 300000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x22); + set_field_value(&cmnda_pll0_fb_div_low, 0x29A); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x06); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 680); + } else if (inside(pixel_freq_khz, 85000, 170000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x11); + set_field_value(&cmnda_pll0_fb_div_low, 0x146); + set_field_value(&cmn_ref_clk_dig_div, 0x00); + set_field_value(÷r_scaler, 0x07); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 340); + } else if (inside(pixel_freq_khz, 42500, 85000)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + set_field_value(&cmnda_pll0_ip_div, 0x08); + set_field_value(&cmnda_pll0_fb_div_low, 0x132); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 320); + } else if (inside(pixel_freq_khz, 25000, 42500)) { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + set_field_value(&cmnda_pll0_ip_div, 0x05); + set_field_value(&cmnda_pll0_fb_div_low, 0x182); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&pll_feedback_divider_total, + 400); + } else { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } + break; + case CLK_RATIO_1_2: + if (!(inside(pixel_freq_khz, 594000, 594000))) { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } else { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + set_field_value(&cmnda_pll0_ip_div, 0x3C); + set_field_value(&cmnda_pll0_fb_div_low, 0x24A); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x06); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 600); + } + break; + case CLK_RATIO_5_8: + if (!(inside(pixel_freq_khz, 594000, 594000))) { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } else { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x3C); + set_field_value(&cmnda_pll0_fb_div_low, 0x169); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x06); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 375); + } + break; + case CLK_RATIO_3_4: + if (!(inside(pixel_freq_khz, 594000, 594000))) { + ftemp = pixel_freq_khz; + debug("Pixel clock frequency (%u) is outside of the supported range\n", + ftemp); + } else { + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + set_field_value(&cmnda_pll0_ip_div, 0x3C); + set_field_value(&cmnda_pll0_fb_div_low, 0x1B4); + set_field_value(&cmn_ref_clk_dig_div, 0x03); + set_field_value(÷r_scaler, 0x06); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&pll_feedback_divider_total, + 450); + } + break; + } + vco_freq = + pixel_freq_khz * pll_feedback_divider_total.value / + cmnda_pll0_ip_div.value; + ftemp = vco_freq; + debug("VCO frequency is %u kHz\n", ftemp); + + if (inside(vco_freq, 1700000, 2000000)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x09); + set_field_value(&ptat_ndac_ctrl, 0x09); + switch (pll_feedback_divider_total.value) { + case 300: + set_field_value(&charge_pump_gain, 0x82); + break; + case 320: + set_field_value(&charge_pump_gain, 0x83); + break; + case 325: + set_field_value(&charge_pump_gain, 0x83); + break; + case 330: + set_field_value(&charge_pump_gain, 0x84); + break; + case 340: + set_field_value(&charge_pump_gain, 0x84); + break; + case 360: + set_field_value(&charge_pump_gain, 0x86); + break; + case 400: + set_field_value(&charge_pump_gain, 0xA2); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 2000000, 2400000)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x09); + set_field_value(&ptat_ndac_ctrl, 0x09); + switch (pll_feedback_divider_total.value) { + case 300: + set_field_value(&charge_pump_gain, 0x47); + break; + case 320: + set_field_value(&charge_pump_gain, 0x4B); + break; + case 325: + set_field_value(&charge_pump_gain, 0x4C); + break; + case 330: + set_field_value(&charge_pump_gain, 0x80); + break; + case 340: + set_field_value(&charge_pump_gain, 0x81); + break; + case 360: + set_field_value(&charge_pump_gain, 0x82); + break; + case 400: + set_field_value(&charge_pump_gain, 0x84); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 2400000, 2800000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 300: + set_field_value(&charge_pump_gain, 0x43); + break; + case 320: + set_field_value(&charge_pump_gain, 0x45); + break; + case 325: + set_field_value(&charge_pump_gain, 0x45); + break; + case 330: + set_field_value(&charge_pump_gain, 0x45); + break; + case 340: + set_field_value(&charge_pump_gain, 0x86); + break; + case 360: + set_field_value(&charge_pump_gain, 0x4A); + break; + case 400: + set_field_value(&charge_pump_gain, 0x81); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 2800000, 3400000)) { + set_field_value(&voltage_to_current_coarse, 0x06); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 300: + set_field_value(&charge_pump_gain, 0x3D); + break; + case 320: + set_field_value(&charge_pump_gain, 0x41); + break; + case 325: + set_field_value(&charge_pump_gain, 0x41); + break; + case 330: + set_field_value(&charge_pump_gain, 0x41); + break; + case 340: + set_field_value(&charge_pump_gain, 0x42); + break; + case 360: + set_field_value(&charge_pump_gain, 0x43); + break; + case 400: + set_field_value(&charge_pump_gain, 0x46); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 3400000, 3900000)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + switch (pll_feedback_divider_total.value) { + case 375: + set_field_value(&charge_pump_gain, 0x41); + break; + case 600: + set_field_value(&charge_pump_gain, 0x82); + break; + case 680: + set_field_value(&charge_pump_gain, 0x85); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 3900000, 4500000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + switch (pll_feedback_divider_total.value) { + case 450: + set_field_value(&charge_pump_gain, 0x41); + break; + case 600: + set_field_value(&charge_pump_gain, 0x4B); + break; + case 680: + set_field_value(&charge_pump_gain, 0x82); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 4500000, 5200000)) { + set_field_value(&voltage_to_current_coarse, 0x06); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 600: + set_field_value(&charge_pump_gain, 0x45); + break; + case 680: + set_field_value(&charge_pump_gain, 0x4A); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else if (inside(vco_freq, 5200000, 6000000)) { + set_field_value(&voltage_to_current_coarse, 0x07); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 600: + set_field_value(&charge_pump_gain, 0x42); + break; + case 680: + set_field_value(&charge_pump_gain, 0x45); + break; + default: + debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", + pll_feedback_divider_total.value, ftemp); + } + } else + debug("VCO frequency %u kHz is outside of the supported range\n", + ftemp); + + /* 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); + write16(0x01CA, reg_val); + /* register CMN_DIAG_PLL0_FBL_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_low); + reg_val |= (1 << 15); + write16(0x01C1, reg_val); + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = read16(0xC800); + reg_val &= 0xCFFF; + reg_val |= set_reg_value(cmn_ref_clk_dig_div); + write16(0xC800, reg_val); + /* register CMN_CDIAG_REFCLK_CTRL */ + reg_val = read16(0x0062); + reg_val &= 0x8FFF; + reg_val |= set_reg_value(divider_scaler); + reg_val |= 0x00C0; + write16(0x0062, reg_val); + /* register CMN_DIAG_HSCLK_SEL */ + reg_val = read16(0x01E0); + reg_val &= 0xFF00; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0; + reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4; + write16(0x01E0, reg_val); + + /* register XCVR_DIAG_HSCLK_SEL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x40E1 | (k << 9)); + reg_val &= 0xCFFF; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12; + write16(0x40E1 | (k << 9), reg_val); + } + + /* register TX_DIAG_TX_CTRL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x41E0 | (k << 9)); + reg_val &= 0xFF3F; + reg_val |= (tx_subrate.value >> 1) << 6; + write16(0x41E0 | (k << 9), reg_val); + } + + /* register CMN_PLLSM0_USER_DEF_CTRL */ + reg_val = set_reg_value(vco_ring_select); + write16(0x002F, reg_val); + /* register CMN_DIAG_PLL0_OVRD */ + write16(0x01C2, 0x0000); + /* register CMN_DIAG_PLL0_FBH_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_high); + reg_val |= (1 << 15); + write16(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); + write16(0x01C5, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */ + reg_val = set_reg_value(pmos_ctrl); + reg_val |= set_reg_value(ndac_ctrl); + write16(0x01C8, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */ + reg_val = set_reg_value(ptat_ndac_ctrl); + write16(0x01C9, reg_val); + /* register CMN_DIAG_PLL0_CP_TUNE */ + reg_val = set_reg_value(charge_pump_gain); + write16(0x01C6, reg_val); + /* register CMN_DIAG_PLL0_LF_PROG */ + write16(0x01C7, 0x0008); + + /* register XCVR_DIAG_PLLDRC_CTRL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x40E0 | (k << 9)); + reg_val &= 0xBFFF; + write16(0x40E0 | (k << 9), reg_val); + } + + } else { + /* Describing task phy_cfg_hdmi_pll0_0pt099_ver2 + (Clock is OUTPUT) */ + if (inside(pixel_freq_khz, 27000, 27000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 240); + set_field_value(&cmnda_pll0_fb_div_low, 0xBC); + set_field_value(&cmnda_pll0_fb_div_high, 0x30); + set_field_value(&cmnda_pll0_pxdiv_low, 0x26); + set_field_value(&cmnda_pll0_pxdiv_high, 0x26); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 300); + set_field_value(&cmnda_pll0_fb_div_low, 0x0EC); + set_field_value(&cmnda_pll0_fb_div_high, 0x03C); + set_field_value(&cmnda_pll0_pxdiv_low, 0x030); + set_field_value(&cmnda_pll0_pxdiv_high, 0x030); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 360); + set_field_value(&cmnda_pll0_fb_div_low, 0x11C); + set_field_value(&cmnda_pll0_fb_div_high, 0x048); + set_field_value(&cmnda_pll0_pxdiv_low, 0x03A); + set_field_value(&cmnda_pll0_pxdiv_high, 0x03A); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 240); + set_field_value(&cmnda_pll0_fb_div_low, 0x0BC); + set_field_value(&cmnda_pll0_fb_div_high, 0x030); + set_field_value(&cmnda_pll0_pxdiv_low, 0x026); + set_field_value(&cmnda_pll0_pxdiv_high, 0x026); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 54000, 54000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 480); + set_field_value(&cmnda_pll0_fb_div_low, 0x17C); + set_field_value(&cmnda_pll0_fb_div_high, 0x060); + set_field_value(&cmnda_pll0_pxdiv_low, 0x026); + set_field_value(&cmnda_pll0_pxdiv_high, 0x026); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 400); + set_field_value(&cmnda_pll0_fb_div_low, 0x13C); + set_field_value(&cmnda_pll0_fb_div_high, 0x050); + set_field_value(&cmnda_pll0_pxdiv_low, 0x017); + set_field_value(&cmnda_pll0_pxdiv_high, 0x017); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 480); + set_field_value(&cmnda_pll0_fb_div_low, 0x17C); + set_field_value(&cmnda_pll0_fb_div_high, 0x060); + set_field_value(&cmnda_pll0_pxdiv_low, 0x01C); + set_field_value(&cmnda_pll0_pxdiv_high, 0x01C); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 240); + set_field_value(&cmnda_pll0_fb_div_low, 0x0bc); + set_field_value(&cmnda_pll0_fb_div_high, 0x030); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 74250, 74250)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x026); + set_field_value(&cmnda_pll0_pxdiv_high, 0x026); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x03); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 550); + set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); + set_field_value(&cmnda_pll0_fb_div_high, 0x06e); + set_field_value(&cmnda_pll0_pxdiv_low, 0x017); + set_field_value(&cmnda_pll0_pxdiv_high, 0x017); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x04); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x01c); + set_field_value(&cmnda_pll0_pxdiv_high, 0x01c); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 330); + set_field_value(&cmnda_pll0_fb_div_low, 0x104); + set_field_value(&cmnda_pll0_fb_div_high, 0x042); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 99000, 99000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 440); + set_field_value(&cmnda_pll0_fb_div_low, 0x15c); + set_field_value(&cmnda_pll0_fb_div_high, 0x058); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 275); + set_field_value(&cmnda_pll0_fb_div_low, 0x0d8); + set_field_value(&cmnda_pll0_fb_div_high, 0x037); + set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); + set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 330); + set_field_value(&cmnda_pll0_fb_div_low, 0x104); + set_field_value(&cmnda_pll0_fb_div_high, 0x042); + set_field_value(&cmnda_pll0_pxdiv_low, 0x00d); + set_field_value(&cmnda_pll0_pxdiv_high, 0x00d); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 440); + set_field_value(&cmnda_pll0_fb_div_low, 0x15c); + set_field_value(&cmnda_pll0_fb_div_high, 0x058); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 148500, 148500)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x02); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 550); + set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); + set_field_value(&cmnda_pll0_fb_div_high, 0x06e); + set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); + set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 495); + set_field_value(&cmnda_pll0_fb_div_low, 0x188); + set_field_value(&cmnda_pll0_fb_div_high, 0x063); + set_field_value(&cmnda_pll0_pxdiv_low, 0x00d); + set_field_value(&cmnda_pll0_pxdiv_high, 0x00d); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x012); + set_field_value(&cmnda_pll0_pxdiv_high, 0x012); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x02); + set_field_value(&cmnda_hs_clk_1_sel, 0x02); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 198000, 198000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 220); + set_field_value(&cmnda_pll0_fb_div_low, 0x0ac); + set_field_value(&cmnda_pll0_fb_div_high, 0x02c); + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_5_4: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 550); + set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); + set_field_value(&cmnda_pll0_fb_div_high, 0x06e); + set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); + set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 330); + set_field_value(&cmnda_pll0_fb_div_low, 0x104); + set_field_value(&cmnda_pll0_fb_div_high, 0x042); + set_field_value(&cmnda_pll0_pxdiv_low, 0x006); + set_field_value(&cmnda_pll0_pxdiv_high, 0x005); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 440); + set_field_value(&cmnda_pll0_fb_div_low, 0x15c); + set_field_value(&cmnda_pll0_fb_div_high, 0x058); + set_field_value(&cmnda_pll0_pxdiv_low, 0x008); + set_field_value(&cmnda_pll0_pxdiv_high, 0x008); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + default: + break; + } + } else if (inside(pixel_freq_khz, 297000, 297000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 330); + set_field_value(&cmnda_pll0_fb_div_low, 0x104); + set_field_value(&cmnda_pll0_fb_div_high, 0x042); + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x00); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_3_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 495); + set_field_value(&cmnda_pll0_fb_div_low, 0x188); + set_field_value(&cmnda_pll0_fb_div_high, 0x063); + set_field_value(&cmnda_pll0_pxdiv_low, 0x006); + set_field_value(&cmnda_pll0_pxdiv_high, 0x005); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_2_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x008); + set_field_value(&cmnda_pll0_pxdiv_high, 0x008); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + default: + ftemp = pixel_freq_khz; + debug("This pixel clock frequency (%u kHz) is not supported with this (%0d-bit) color depth.\n", + ftemp, bpp); + } + } else if (inside(pixel_freq_khz, 594000, 594000)) { + switch (clk_ratio) { + case CLK_RATIO_1_1: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_1_2: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 660); + set_field_value(&cmnda_pll0_fb_div_low, 0x20c); + set_field_value(&cmnda_pll0_fb_div_high, 0x084); + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x02); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x01); + break; + case CLK_RATIO_5_8: + set_field_value(&cmnda_pll0_ip_div, 0x04); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 550); + set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); + set_field_value(&cmnda_pll0_fb_div_high, 0x06e); + /* does not matter - pixel clock delivered to + controller from SoC */ + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + /* does not matter - pixel clock delivered to + controller from SoC */ + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + case CLK_RATIO_3_4: + set_field_value(&cmnda_pll0_ip_div, 0x03); + set_field_value(&cmn_ref_clk_dig_div, 0x01); + set_field_value(÷r_scaler, 0x01); + set_field_value(&pll_feedback_divider_total, + 495); + set_field_value(&cmnda_pll0_fb_div_low, 0x188); + set_field_value(&cmnda_pll0_fb_div_high, 0x063); + /* does not matter - pixel clock delivered to + controller from SoC */ + set_field_value(&cmnda_pll0_pxdiv_low, 0x003); + /* does not matter - pixel clock delivered to + controller from SoC */ + set_field_value(&cmnda_pll0_pxdiv_high, 0x003); + set_field_value(&vco_ring_select, 0x01); + set_field_value(&cmnda_hs_clk_0_sel, 0x01); + set_field_value(&cmnda_hs_clk_1_sel, 0x01); + set_field_value(&tx_subrate, 0x01); + set_field_value(&cmnda_pll0_hs_sym_div_sel, + 0x00); + break; + default: + debug("This pixel clock frequency (%d KHz) is not supported with this (%0d-bit) color depth.\n", + pixel_freq_khz, bpp); + } + } else { + ftemp = pixel_freq_khz; + debug("This pixel clock frequency (%u kHz) is not supported.\n", + ftemp); + } + + vco_freq = + refclk_freq_khz * pll_feedback_divider_total.value / + cmnda_pll0_ip_div.value; + ftemp = vco_freq; + debug("VCO frequency is %u kHz\n", ftemp); + + if (inside(vco_freq, 1980000, 1980000)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x09); + set_field_value(&ptat_ndac_ctrl, 0x09); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 160); + set_field_value(&v2i_code, 5); + set_field_value(&vco_cal_code, 183); + } else if (inside(vco_freq, 2160000, 2160000)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x09); + set_field_value(&ptat_ndac_ctrl, 0x09); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 166); + set_field_value(&v2i_code, 6); + set_field_value(&vco_cal_code, 208); + } else if (inside(vco_freq, 2475000, 2475000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 167); + set_field_value(&v2i_code, 6); + set_field_value(&vco_cal_code, 209); + } else if (inside(vco_freq, 2700000, 2700000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 300: + set_field_value(&charge_pump_gain, 0x042); + break; + case 400: + set_field_value(&charge_pump_gain, 0x04c); + break; + } + set_field_value(&coarse_code, 188); + set_field_value(&v2i_code, 6); + set_field_value(&vco_cal_code, 225); + } else if (inside(vco_freq, 2970000, 2970000)) { + set_field_value(&voltage_to_current_coarse, 0x06); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 183); + set_field_value(&v2i_code, 6); + set_field_value(&vco_cal_code, 225); + } else if (inside(vco_freq, 3240000, 3240000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + switch (pll_feedback_divider_total.value) { + case 360: + set_field_value(&charge_pump_gain, 0x042); + break; + case 480: + set_field_value(&charge_pump_gain, 0x04c); + break; + } + set_field_value(&coarse_code, 203); + set_field_value(&v2i_code, 7); + set_field_value(&vco_cal_code, 256); + } else if (inside(vco_freq, 3712500, 3712500)) { + set_field_value(&voltage_to_current_coarse, 0x04); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + set_field_value(&charge_pump_gain, 0x04c); + set_field_value(&coarse_code, 212); + set_field_value(&v2i_code, 7); + set_field_value(&vco_cal_code, 257); + } else if (inside(vco_freq, 3960000, 3960000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 184); + set_field_value(&v2i_code, 6); + set_field_value(&vco_cal_code, 226); + } else if (inside(vco_freq, 4320000, 4320000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 205); + set_field_value(&v2i_code, 7); + set_field_value(&vco_cal_code, 258); + } else if (inside(vco_freq, 4455000, 4455000)) { + set_field_value(&voltage_to_current_coarse, 0x05); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x00); + set_field_value(&pmos_ctrl, 0x07); + set_field_value(&ptat_ndac_ctrl, 0x0F); + switch (pll_feedback_divider_total.value) { + case 495: + set_field_value(&charge_pump_gain, 0x042); + break; + case 660: + set_field_value(&charge_pump_gain, 0x04c); + break; + } + set_field_value(&coarse_code, 219); + set_field_value(&v2i_code, 7); + set_field_value(&vco_cal_code, 272); + } else if (inside(vco_freq, 4950000, 4950000)) { + set_field_value(&voltage_to_current_coarse, 0x06); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 213); + set_field_value(&v2i_code, 7); + set_field_value(&vco_cal_code, 258); + } else if (inside(vco_freq, 5940000, 5940000)) { + set_field_value(&voltage_to_current_coarse, 0x07); + set_field_value(&voltage_to_current, 0x03); + set_field_value(&ndac_ctrl, 0x01); + set_field_value(&pmos_ctrl, 0x00); + set_field_value(&ptat_ndac_ctrl, 0x07); + set_field_value(&charge_pump_gain, 0x042); + set_field_value(&coarse_code, 244); + set_field_value(&v2i_code, 8); + set_field_value(&vco_cal_code, 292); + } else { + ftemp = vco_freq; + debug("Current vco_freq (%u kHz) is not supported.\n", + ftemp); + } + + /* register CMN_PLL0_VCOCAL_INIT_TMR */ + write16(0x0084, 0x0064); + /* register CMN_PLL0_VCOCAL_ITER_TMR */ + write16(0x0085, 0x000A); + /* register PHY_HDP_CLK_CTL */ + reg_val = read16(0xC009); + reg_val &= 0x00FF; + reg_val |= 0x2 << 8; + reg_val |= 0x1 << 12; + write16(0xC009, reg_val); + /* register 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(0x01CA, reg_val); + /* register CMN_DIAG_PLL0_FBH_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_high); + reg_val |= (1 << 15); + write16(0x01C0, reg_val); + /* register CMN_DIAG_PLL0_FBL_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_low); + reg_val |= (1 << 15); + write16(0x01C1, reg_val); + /* register CMN_DIAG_PLL0_PXL_DIVL */ + reg_val = set_reg_value(cmnda_pll0_pxdiv_low); + write16(0x01CC, reg_val); + /* register CMN_DIAG_PLL0_PXL_DIVH */ + reg_val = set_reg_value(cmnda_pll0_pxdiv_high); + reg_val |= (1 << 15); + write16(0x01CB, reg_val); + + /* register TX_DIAG_TX_CTRL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x41E0 | (k << 9)); + reg_val &= 0xFF3F; + reg_val |= (tx_subrate.value >> 1) << 6; + write16(0x41E0 | (k << 9), reg_val); + } + + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = read16(0xC800); + reg_val &= 0xCFFF; + reg_val |= set_reg_value(cmn_ref_clk_dig_div); + write16(0xC800, reg_val); + /* register CMN_CDIAG_REFCLK_CTRL */ + reg_val = read16(0x0062); + reg_val &= 0x8FFF; + reg_val |= set_reg_value(divider_scaler); + reg_val |= 0x00C0; + write16(0x0062, reg_val); + /* register CMN_DIAG_HSCLK_SEL */ + reg_val = read16(0x01E0); + reg_val &= 0xFF00; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0; + reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4; + write16(0x01E0, reg_val); + /* register CMN_PLLSM0_USER_DEF_CTRL */ + reg_val = set_reg_value(vco_ring_select); + write16(0x002F, reg_val); + + /* register XCVR_DIAG_HSCLK_SEL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x40E1 | (k << 9)); + reg_val &= 0xCFFF; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12; + write16(0x40E1 | (k << 9), reg_val); + } + + /* register CMN_DIAG_PLL0_OVRD */ + write16(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); + write16(0x01C5, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */ + reg_val = set_reg_value(pmos_ctrl); + reg_val |= set_reg_value(ndac_ctrl); + write16(0x01C8, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */ + reg_val = set_reg_value(ptat_ndac_ctrl); + write16(0x01C9, reg_val); + /* register CMN_PLL0_VCOCAL_START */ + reg_val = read16(0x0081); + reg_val &= 0xFE00; + reg_val |= set_reg_value(vco_cal_code); + write16(0x0081, reg_val); + /* register CMN_DIAG_PLL0_CP_TUNE */ + reg_val = set_reg_value(charge_pump_gain); + write16(0x01C6, reg_val); + /* register CMN_DIAG_PLL0_LF_PROG */ + write16(0x01C7, 0x0008); + + /* register XCVR_DIAG_PLLDRC_CTRL */ + for (k = 0; k < num_lanes; k++) { + reg_val = read16(0x40E0 | (k << 9)); + reg_val &= 0xBFFF; + write16(0x40E0 | (k << 9), reg_val); + } + } + + /* Back to task phy_cfg_hdp */ + + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = read16(0xC800); + reg_val &= 0xFF8F; + /* for differential clock on the refclk_p and refclk_m + * off chip pins: PHY_PMA_CMN_CTRL1[6:4]=3'b000 */ + reg_val |= 0x0000; + write16(0xC800, reg_val); + + /* register CMN_DIAG_ACYA */ + write16(0x01FF, 0x0100); + + if (phy_reset_workaround) { + /* register PHY_ISO_CMN_CTRL */ + write16(0xC010, 0x0001); /* Deassert PHY reset */ + /* register PHY_PMA_ISO_CMN_CTRL */ + write16(0xC810, 0x0003); + for (k = 0; k < num_lanes; k++) { + /* register XCVR_PSM_RCTRL */ + write16(0x4001 | (k << 9), 0xFEFC); + } + /* register PHY_PMA_ISO_CMN_CTRL + * Assert cmn_macro_pwr_en*/ + write16(0xC810, 0x0013); + + /* PHY_PMA_ISO_CMN_CTRL + * wait for cmn_macro_pwr_en_ack*/ + while (!(read16(0xC810) & (1 << 5))) + ; + + /* PHY_PMA_CMN_CTRL1 wait for cmn_ready */ + while (!(read16(0xC800) & (1 << 0))) + ; + } else { + for (k = 0; k < num_lanes; k++) { + /* register XCVR_PSM_RCTRL */ + write16(0x4001 | (k << 9), 0xBEFC); + } + } + for (k = 0; k < num_lanes; k++) { + /* register TX_PSC_A0 */ + write16(0x4100 | (k << 9), 0x6791); + /* register TX_PSC_A1 */ + write16(0x4101 | (k << 9), 0x6790); + /* register TX_PSC_A2 */ + write16(0x4102 | (k << 9), 0x0090); + /* register TX_PSC_A3 */ + write16(0x4103 | (k << 9), 0x0090); + /* register RX_PSC_CAL */ + reg_val = read16(0x8006 | (k << 9)); + reg_val &= 0xFFBB; + write16(0x8006 | (k << 9), reg_val); + reg_val = read16(0x8000 | (k << 9)); + reg_val &= 0xFFBB; + write16(0x8000 | (k << 9), reg_val); + } + + /* End of task phy_cfg_hdp */ + /* register PHY_HDP_MODE_CTL */ + write16(0xC008, 0x0004); + + aux_cfg_t28hpc(); + return character_freq_khz; +} + +int hdmi_tx_t28hpc_power_config_seq(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 */ + write16(0x41FF | (k << 9), 0x0001); + } + + /* register PHY_DP_MODE_CTL */ + while (!(read16(0xC008) & (1 << 6))) + ; + + /* PHY_DP_MODE_CTL */ + write16(0xC008, (((0x0F << num_lanes) & 0x0F) << 12) | 0x0101); + + /* PHY_DP_MODE_CTL */ + while (!(read16(0xC008) & (1 << 4))) + ; + + return 0; +} diff --git a/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.h b/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.h new file mode 100644 index 000000000000..756c1d577e1d --- /dev/null +++ b/drivers/video/imx/hdp/API_AFE_t28hpc_hdmitx.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_t28hpc_hdmitx.h + * + ****************************************************************************** + */ + +#ifndef API_AFE_T28HPC_HDMITX_H_ +#define API_AFE_T28HPC_HDMITX_H_ + +#ifndef __UBOOT__ +#include +#include +#else +#include +#endif +#include "vic_table.h" +#include "API_AFE.h" +#include "externs.h" + +int phy_cfg_t28hpc(int num_lanes, VIC_MODES vic_mode, int bpp, + VIC_PXL_ENCODING_FORMAT format, bool pixel_clk_from_phy); +int hdmi_tx_t28hpc_power_config_seq(int num_lanes); + +#endif diff --git a/drivers/video/imx/hdp/API_AVI.c b/drivers/video/imx/hdp/API_AVI.c new file mode 100644 index 000000000000..d9346f237585 --- /dev/null +++ b/drivers/video/imx/hdp/API_AVI.c @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_AVI.c + * + ****************************************************************************** + */ + +#include "API_AVI.h" +#include "API_Infoframe.h" + +CDN_API_STATUS cdn_api_set_avi(VIC_MODES vic_mode, + VIC_PXL_ENCODING_FORMAT color_mode, + BT_TYPE itu_ver) +{ + unsigned int active_slot = vic_table[vic_mode][H_BLANK]; + unsigned int line_width = vic_table[vic_mode][H_TOTAL]; + unsigned int hactive = line_width - active_slot + 1; + unsigned int vactive = vic_table[vic_mode][V_ACTIVE] + 1; + + unsigned int hactive_l = hactive - 256 * ((unsigned int)hactive / 256); + unsigned int hactive_h = hactive / 256; + unsigned int vactive_l = vactive - 256 * ((unsigned int)vactive / 256); + unsigned int vactive_h = vactive / 256; + + /* unsigned int packet; */ + + unsigned int packet_type = 0x82; + unsigned int packet_version = 0x2; + unsigned int packet_len = 0xd; + unsigned int packet_y = 0; + unsigned int packet_c = 0; + unsigned int packet_r = 0; + unsigned int packet_vic = 0; + unsigned int packet_pr = 0; + unsigned int packet_buf[18 / sizeof(unsigned int)]; + unsigned char *packet = (unsigned char *)&packet_buf[0]; + unsigned int packet_hb0 = 0; + unsigned int packet_hb1 = 0; + unsigned int packet_hb2 = 0; + unsigned int packet_pb0 = 0; + unsigned int packet_pb1 = 0; + unsigned int packet_pb2 = 0; + unsigned int packet_pb3 = 0; + unsigned int packet_pb4 = 0; + unsigned int packet_pb5 = 0; + unsigned int packet_pb6 = 0; + unsigned int packet_pb7 = 0; + unsigned int packet_pb8 = 0; + unsigned int packet_pb9 = 0; + unsigned int packet_pb10 = 0; + unsigned int packet_pb11 = 0; + unsigned int packet_pb12 = 0; + unsigned int packet_pb13 = 0; + unsigned int pb1_13_chksum = 0; + unsigned int packet_chksum = 0; + + if (color_mode == PXL_RGB) + packet_y = 0; + else if (color_mode == YCBCR_4_4_4) + packet_y = 2; + else if (color_mode == YCBCR_4_2_2) + packet_y = 1; + else if (color_mode == YCBCR_4_2_0) + packet_y = 3; + + /* Colorimetry: Nodata=0 IT601=1 ITU709=2 */ + if (itu_ver == BT_601) + packet_c = 1; + else if (itu_ver == BT_709) + packet_c = 2; + else + packet_c = 0; + + unsigned int packet_a0 = 1; + unsigned int packet_b = 0; + unsigned int packet_s = 0; + unsigned int packet_sc = 0; /* Picture Scaling */ + + /* Active Format Aspec Ratio: Same As Picture = 0x8 4:3(Center)=0x9 + 16:9=0xA 14:9=0xB */ + packet_r = vic_table[vic_mode][VIC_R3_0]; + /* Aspect Ratio: Nodata=0 4:3=1 16:9=2 */ + unsigned int packet_m = 0; + /* Quantization Range Default=0 Limited Range=0x1 FullRange=0x2 + Reserved 0x3 */ + unsigned int packet_q = 0; + /* Quantization Range 0=Limited Range FullRange=0x1 Reserved 0x3/2 */ + unsigned int packet_yq = 0; + /* Extended Colorimetry xvYCC601=0x0 xvYCC709=1 All other Reserved */ + unsigned int packet_ec = 0; + /*IT content nodata=0 ITcontent=1 */ + unsigned int packet_it = 0; + /* Video Code (CEA) */ + packet_vic = vic_table[vic_mode][VIC]; + /* Pixel Repetition 0 ... 9 (1-10) */ + packet_pr = vic_table[vic_mode][VIC_PR]; + /* Content Type */ + unsigned int packet_cn = 0; + + packet_hb0 = packet_type; + packet_hb1 = packet_version; + packet_hb2 = packet_len; + + packet_pb1 = 32 * packet_y + 16 * packet_a0 + 4 * packet_b + packet_s; + packet_pb2 = 64 * packet_c + 16 * packet_m + packet_r; + packet_pb3 = + 128 * packet_it + 16 * packet_ec + 4 * packet_q + packet_sc; + packet_pb4 = packet_vic; + packet_pb5 = 64 * packet_yq + 16 * packet_cn + packet_pr; + packet_pb6 = 0; + packet_pb7 = 0; + packet_pb8 = vactive_l; + packet_pb9 = vactive_h; + packet_pb10 = 0; + packet_pb11 = 0; + packet_pb12 = hactive_l; + packet_pb13 = hactive_h; + + pb1_13_chksum = + (packet_hb0 + packet_hb1 + packet_hb2 + packet_pb1 + + packet_pb2 + packet_pb3 + packet_pb4 + packet_pb5 + + packet_pb6 + packet_pb7 + packet_pb8 + packet_pb9 + + packet_pb10 + packet_pb11 + packet_pb12 + packet_pb13); + packet_chksum = + 256 - (pb1_13_chksum - + 256 * ((unsigned int)pb1_13_chksum / 256)); + packet_pb0 = packet_chksum; + + packet[0] = 0; + packet[1] = packet_hb0; + packet[2] = packet_hb1; + packet[3] = packet_hb2; + packet[4] = packet_pb0; + packet[5] = packet_pb1; + packet[6] = packet_pb2; + packet[7] = packet_pb3; + packet[8] = packet_pb4; + packet[9] = packet_pb5; + packet[10] = packet_pb6; + packet[11] = packet_pb7; + packet[12] = packet_pb8; + packet[13] = packet_pb9; + packet[14] = packet_pb10; + packet[15] = packet_pb11; + packet[16] = packet_pb12; + packet[17] = packet_pb13; + + cdn_api_infoframeset(0, packet_len, + (unsigned int *)&packet[0], packet_type); + + return CDN_OK; +} /* End API */ diff --git a/drivers/video/imx/hdp/API_AVI.h b/drivers/video/imx/hdp/API_AVI.h new file mode 100644 index 000000000000..08c35fa39762 --- /dev/null +++ b/drivers/video/imx/hdp/API_AVI.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_AVI.h + * + ****************************************************************************** + */ + +#ifndef API_AVI_H_ +#define API_AVI_H_ + +#include "vic_table.h" +#include "API_General.h" + +CDN_API_STATUS cdn_api_set_avi( + VIC_MODES vic_mode, + VIC_PXL_ENCODING_FORMAT color_mode, + BT_TYPE itu_ver); + +#endif /*API_AVI_H_ */ diff --git a/drivers/video/imx/hdp/API_General.c b/drivers/video/imx/hdp/API_General.c new file mode 100644 index 000000000000..fb606558c2dc --- /dev/null +++ b/drivers/video/imx/hdp/API_General.c @@ -0,0 +1,477 @@ +/****************************************************************************** + * + * 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 "util.h" +#ifndef __UBOOT__ +#include +#endif +#include "address.h" +#include "apb_cfg.h" +#include "opcodes.h" +#include "general_handler.h" +#include "externs.h" +#ifndef __UBOOT__ +#include +#endif + +extern state_struct state; + +void cdn_api_init(void) +{ + memset(&state, 0, sizeof(state_struct)); +} + +CDN_API_STATUS cdn_api_loadfirmware(unsigned char *imem, int imemsize, + unsigned char *dmem, int dmemsize) +{ + int i; + for (i = 0; i < imemsize; i += 4) + if (cdn_apb_write(ADDR_IMEM + i, + (unsigned int)imem[i] << 0 | + (unsigned int)imem[i + 1] << 8 | + (unsigned int)imem[i + 2] << 16 | + (unsigned int)imem[i + 3] << 24)) + return CDN_ERR; + for (i = 0; i < dmemsize; i += 4) + if (cdn_apb_write(ADDR_DMEM + i, + (unsigned int)dmem[i] << 0 | + (unsigned int)dmem[i + 1] << 8 | + (unsigned int)dmem[i + 2] << 16 | + (unsigned int)dmem[i + 3] << 24)) + return CDN_ERR; + return CDN_OK; +} + +CDN_API_STATUS cdn_api_general_test_echo(unsigned int val, + CDN_BUS_TYPE bus_type) +{ + CDN_API_STATUS ret; + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + state.bus_type = bus_type; + state.rxenable = 1; + internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO, + 1, 4, val); + return CDN_STARTED; + } + if (state.txenable && !internal_mbox_tx_process().txend) + return CDN_BSY; + if (state.rxenable && !internal_mbox_rx_process().rxend) + return CDN_BSY; + ret = internal_test_rx_head(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(unsigned int val, + CDN_BUS_TYPE bus_type) +{ + internal_block_function(cdn_api_general_test_echo(val, bus_type)); +} + +CDN_API_STATUS cdn_api_general_test_echo_ext(uint8_t const *msg, uint8_t *resp, + uint16_t 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()) + return CDN_BSY; + + state.bus_type = bus_type; + state.rxenable = 1; + + internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO, + 1, -num_bytes, msg); + + return CDN_STARTED; + } + + if (state.txenable && !internal_mbox_tx_process().txend) + return CDN_BSY; + + if (state.rxenable && !internal_mbox_rx_process().rxend) + return CDN_BSY; + + ret = internal_test_rx_head(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(uint8_t const *msg, + uint8_t *resp, + uint16_t num_bytes, + CDN_BUS_TYPE bus_type) +{ + internal_block_function(cdn_api_general_test_echo_ext + (msg, resp, num_bytes, bus_type) + ); +} + +CDN_API_STATUS cdn_api_general_getcurversion(unsigned short *ver, + unsigned short *verlib) +{ + unsigned int vh, vl, vlh, vll; + if (cdn_apb_read(VER_L << 2, &vl)) + return CDN_ERR; + if (cdn_apb_read(VER_H << 2, &vh)) + return CDN_ERR; + if (cdn_apb_read(VER_LIB_L_ADDR << 2, &vll)) + return CDN_ERR; + if (cdn_apb_read(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(uint32_t *events) +{ + uint32_t evt[4] = { 0 }; + + if (!events) { + printf("events pointer is NULL!\n"); + return CDN_ERR; + } + + if (cdn_apb_read(SW_EVENTS0 << 2, &evt[0]) || + cdn_apb_read(SW_EVENTS1 << 2, &evt[1]) || + cdn_apb_read(SW_EVENTS2 << 2, &evt[2]) || + cdn_apb_read(SW_EVENTS3 << 2, &evt[3])) { + printf("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(uint16_t *val) +{ + uint32_t dbg[2] = { 0 }; + + if (!val) { + printf("val pointer is NULL!\n"); + return CDN_ERR; + } + + if (cdn_apb_read(SW_DEBUG_L << 2, &dbg[0]) || + cdn_apb_read(SW_DEBUG_H << 2, &dbg[1])) { + printf("Failed to read debug registers.\n"); + return CDN_ERR; + } + + *val = (uint16_t) ((dbg[0] & 0xFF) | ((dbg[1] & 0xFF) << 8)); + + return CDN_OK; +} + +CDN_API_STATUS cdn_api_checkalive(void) +{ + static unsigned int alive; + unsigned int newalive; + if (cdn_apb_read(KEEP_ALIVE << 2, &newalive)) + return CDN_ERR; + if (alive == newalive) + return CDN_BSY; + alive = newalive; + return CDN_OK; +} + +CDN_API_STATUS cdn_api_checkalive_blocking(void) +{ + internal_block_function(cdn_api_checkalive()); +} + +CDN_API_STATUS cdn_api_maincontrol(unsigned char mode, unsigned char *resp) +{ + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + state.bus_type = CDN_BUS_TYPE_APB; + state.rxenable = 1; + internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, + GENERAL_MAIN_CONTROL, 1, 1, mode); + return CDN_STARTED; + } + INTERNAL_PROCESS_MESSAGES; + internal_opcode_ok_or_return(MB_MODULE_ID_GENERAL, + GENERAL_MAIN_CONTROL_RESP); + internal_readmsg(1, 1, resp); + return CDN_OK; +} + +CDN_API_STATUS cdn_api_maincontrol_blocking(unsigned char mode, + unsigned char *resp) +{ + internal_block_function(cdn_api_maincontrol(mode, resp)); +} + +CDN_API_STATUS cdn_api_apbconf(uint8_t dpcd_bus_sel, uint8_t dpcd_bus_lock, + uint8_t hdcp_bus_sel, uint8_t hdcp_bus_lock, + uint8_t capb_bus_sel, uint8_t capb_bus_lock, + uint8_t *dpcd_resp, uint8_t *hdcp_resp, + uint8_t *capb_resp) +{ + uint8_t resp; + uint8_t set = 0; + + if (!state.running) { + if (!internal_apb_available()) + 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(MB_MODULE_ID_GENERAL, + GENERAL_BUS_SETTINGS, 1, 1, set); + + return CDN_STARTED; + } + + INTERNAL_PROCESS_MESSAGES; + internal_opcode_ok_or_return(MB_MODULE_ID_GENERAL, + GENERAL_BUS_SETTINGS_RESP); + + /* Read one one-byte response */ + internal_readmsg(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(uint8_t dpcd_bus_sel, + uint8_t dpcd_bus_lock, + uint8_t hdcp_bus_sel, + uint8_t hdcp_bus_lock, + uint8_t capb_bus_sel, + uint8_t capb_bus_lock, + uint8_t *dpcd_resp, + uint8_t *hdcp_resp, + uint8_t *capb_resp) +{ + internal_block_function(cdn_api_apbconf(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(unsigned char mhz) +{ + return cdn_apb_write(SW_CLK_H << 2, mhz); +} + +CDN_API_STATUS cdn_api_general_read_register(unsigned int addr, + GENERAL_READ_REGISTER_RESPONSE + *resp) +{ + CDN_API_STATUS ret; + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + internal_tx_mkfullmsg(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; + ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, + GENERAL_READ_REGISTER_RESP); + if (ret != CDN_OK) + return ret; + internal_readmsg(2, 4, &resp->addr, 4, &resp->val); + return CDN_OK; +} + +CDN_API_STATUS +cdn_api_general_read_register_blocking(unsigned int addr, + GENERAL_READ_REGISTER_RESPONSE *resp) +{ + internal_block_function(cdn_api_general_read_register(addr, resp)); +} + +CDN_API_STATUS cdn_api_general_write_register(unsigned int addr, + unsigned int val) +{ + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + internal_tx_mkfullmsg(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; + return CDN_OK; +} + +CDN_API_STATUS cdn_api_general_write_register_blocking(unsigned int addr, + unsigned int val) +{ + internal_block_function(cdn_api_general_write_register(addr, val)); +} + +CDN_API_STATUS cdn_api_general_write_field(unsigned int addr, + unsigned char startbit, + unsigned char bitsno, + unsigned int val) +{ + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + internal_tx_mkfullmsg(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; + return CDN_OK; +} + +CDN_API_STATUS cdn_api_general_write_field_blocking(unsigned int addr, + unsigned char startbit, + unsigned char bitsno, + unsigned int val) +{ + internal_block_function(cdn_api_general_write_field + (addr, startbit, bitsno, val)); +} + +CDN_API_STATUS cdn_api_general_phy_test_access(uint8_t *resp) +{ + CDN_API_STATUS ret; + + *resp = 0; + + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + + internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ACCESS, + 0); + state.bus_type = CDN_BUS_TYPE_APB; + state.rxenable = 1; + + return CDN_STARTED; + } + + INTERNAL_PROCESS_MESSAGES; + + ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, GENERAL_TEST_ACCESS); + + if (ret != CDN_OK) + return ret; + + internal_readmsg(1, 1, resp); + + return CDN_OK; +} + +CDN_API_STATUS cdn_api_general_phy_test_access_blocking(uint8_t *resp) +{ + internal_block_function(cdn_api_general_phy_test_access(resp)); +} diff --git a/drivers/video/imx/hdp/API_General.h b/drivers/video/imx/hdp/API_General.h new file mode 100644 index 000000000000..e631919f5715 --- /dev/null +++ b/drivers/video/imx/hdp/API_General.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * 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_ + +#ifndef __UBOOT__ +#include +#else +#include +#endif + +#define GENERAL_TEST_ECHO_MAX_PAYLOAD 100 +#define GENERAL_TEST_ECHO_MIN_PAYLOAD 1 + +/** + * \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_BUS_TYPE_APB = 0, + CDN_BUS_TYPE_SAPB = 1 +} CDN_BUS_TYPE; + +/** + * GENERAL_Read_Register response struct + */ +typedef struct { + unsigned int addr; + unsigned int val; +} GENERAL_READ_REGISTER_RESPONSE; + +/** + * \brief set up API, must be called before any other API call + */ +void cdn_api_init(void); + +/** + * \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(unsigned char *imem, + int imemsize, + unsigned char *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(unsigned int val, + CDN_BUS_TYPE bus_type); + +/** + * \brief blocking version of #CDN_API_General_Test_Echo + */ +CDN_API_STATUS cdn_api_general_test_echo_blocking(unsigned int 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(uint8_t const *msg, uint8_t *resp, + uint16_t 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(uint8_t const *msg, + uint8_t *resp, + uint16_t 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(unsigned short *ver, + unsigned short *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(uint32_t *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(uint16_t *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(void); + +/** + * \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(void); + +/** + * \brief set cpu to standby or active + * \param [in] state - 1 for active, 0 for standby + * \return status + */ +CDN_API_STATUS cdn_api_maincontrol(unsigned char mode, unsigned char *resp); + +/** + * \breif blocking version of #CDN_API_MainControl + */ +CDN_API_STATUS cdn_api_maincontrol_blocking(unsigned char mode, + unsigned char *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(uint8_t dpcd_bus_sel, uint8_t dpcd_bus_lock, + uint8_t hdcp_bus_sel, uint8_t hdcp_bus_lock, + uint8_t capb_bus_sel, uint8_t capb_bus_lock, + uint8_t *dpcd_resp, uint8_t *hdcp_resp, + uint8_t *capb_resp); + +/** + * blocking version of #CDN_API_MainControl + */ +CDN_API_STATUS cdn_api_apbconf_blocking(uint8_t dpcd_bus_sel, + uint8_t dpcd_bus_lock, + uint8_t hdcp_bus_sel, + uint8_t hdcp_bus_lock, + uint8_t capb_bus_sel, + uint8_t capb_bus_lock, + uint8_t *dpcd_resp, + uint8_t *hdcp_resp, + uint8_t *capb_resp); + +/** + * \brief set the xtensa clk, write this api before turn on the cpu + */ +CDN_API_STATUS cdn_api_setclock(unsigned char mhz); + +CDN_API_STATUS cdn_api_general_read_register(unsigned int addr, + GENERAL_READ_REGISTER_RESPONSE + *resp); +CDN_API_STATUS +cdn_api_general_read_register_blocking(unsigned int addr, + GENERAL_READ_REGISTER_RESPONSE *resp); +CDN_API_STATUS cdn_api_general_write_register(unsigned int addr, + unsigned int val); +CDN_API_STATUS cdn_api_general_write_register_blocking(unsigned int addr, + unsigned int val); +CDN_API_STATUS cdn_api_general_write_field(unsigned int addr, + unsigned char startbit, + unsigned char bitsno, + unsigned int val); +CDN_API_STATUS cdn_api_general_write_field_blocking(unsigned int addr, + unsigned char startbit, + unsigned char bitsno, + unsigned int val); +CDN_API_STATUS cdn_api_general_phy_test_access(uint8_t *resp); +CDN_API_STATUS cdn_api_general_phy_test_access_blocking(uint8_t *resp); + +#endif diff --git a/drivers/video/imx/hdp/API_HDMITX.c b/drivers/video/imx/hdp/API_HDMITX.c new file mode 100644 index 000000000000..e3e4eb0e3055 --- /dev/null +++ b/drivers/video/imx/hdp/API_HDMITX.c @@ -0,0 +1,485 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_HDMITX.c + * + ****************************************************************************** + */ + +#include "API_HDMITX.h" +#include "util.h" +#include "opcodes.h" +#ifndef __UBOOT__ +#include "string.h" +#include "stdio.h" +#endif +#include "mhl_hdtx_top.h" +#include "source_phy.h" +#include "address.h" +#include "source_car.h" +#include "source_vif.h" +#include "general_handler.h" + +CDN_API_STATUS CDN_API_HDMITX_DDC_READ(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out) +{ + internal_macro_command_txrx(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(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(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out) +{ + internal_block_function(CDN_API_HDMITX_DDC_READ(data_in, data_out)); +} + +CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out) +{ + printf("foo: %x\n", data_in->buff[0]); + internal_macro_command_txrx(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(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(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out) +{ + internal_block_function(CDN_API_HDMITX_DDC_WRITE(data_in, data_out)); +} + +CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ(HDMITX_TRANS_DATA *data_out) +{ + internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_UPDATE_READ, + CDN_BUS_TYPE_APB, 0); + internal_readmsg(2, + 1, &data_out->status, + 0, &data_out->buff + ); + return CDN_OK; +} + +CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ_blocking(HDMITX_TRANS_DATA + *data_out) +{ + internal_block_function(CDN_API_HDMITX_DDC_UPDATE_READ(data_out)); +} + +CDN_API_STATUS CDN_API_HDMITX_READ_EDID(unsigned char block, + unsigned char segment, + HDMITX_TRANS_DATA *data_out) +{ + internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID, + CDN_BUS_TYPE_APB, 2, + 1, block, + 1, segment + ); + internal_readmsg(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(unsigned char block, + unsigned char segment, + HDMITX_TRANS_DATA *data_out) +{ + internal_block_function(CDN_API_HDMITX_READ_EDID(block, segment, + data_out)); +} + +CDN_API_STATUS +CDN_API_HDMITX_Set_Mode_blocking(HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol, + unsigned int character_rate) +{ + CDN_API_STATUS ret; + GENERAL_READ_REGISTER_RESPONSE resp; + HDMITX_TRANS_DATA data_in; + HDMITX_TRANS_DATA data_out; + unsigned char buff = 1; + + /*enable/disable scrambler; */ + if (protocol == HDMI_TX_MODE_HDMI_2_0) { + if (character_rate > 340000) + buff = 3; /*enable scrambling + TMDS_Bit_Clock_Ratio */ + else + buff = 1; /*enable scrambling */ + } else { + buff = 0; /*disable scrambling */ + } + + data_in.buff = &buff; + data_in.len = 1; + data_in.slave = 0x54; + data_in.offset = 0x20; /*TMDS config */ +#if 1 + if (protocol == HDMI_TX_MODE_HDMI_2_0) + ret = CDN_API_HDMITX_DDC_WRITE_blocking(&data_in, &data_out); + +#endif + ret = cdn_api_general_read_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + &resp); + + /*remove data enable */ + resp.val = resp.val & (~(F_DATA_EN(1))); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + if (protocol == HDMI_TX_MODE_HDMI_2_0) { + if (character_rate > 3400000) { + /* Set TMDS clock ratio */ + ret = cdn_api_general_write_register_blocking + (ADDR_SOURCE_MHL_HD + + (HDTX_CLOCK_REG_0 << 2), + F_DATA_REGISTER_VAL_0(0x00000)); + ret = cdn_api_general_write_register_blocking + (ADDR_SOURCE_MHL_HD + + (HDTX_CLOCK_REG_1 << 2), + F_DATA_REGISTER_VAL_1(0xFFFFF)); + } + } + + /*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(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + /*data enable */ + resp.val |= F_DATA_EN(1); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + return ret; +} + +CDN_API_STATUS CDN_API_HDMITX_Init_blocking(void) +{ + CDN_API_STATUS ret; + + /*init phy and CAR and HDMI TX */ +/* ret = cdn_api_general_write_register_blocking + (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)); */ + + ret = cdn_api_general_write_register_blocking(ADDR_SOURCD_PHY + + (PHY_DATA_SEL << 2), + F_SOURCE_PHY_MHDP_SEL(1)); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_HPD << 2), + F_HPD_VALID_WIDTH(4) | + F_HPD_GLITCH_WIDTH(0)); + ret = cdn_api_general_write_register_blocking(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)); + /* open CARS */ + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_PHY_CAR << 2), + 0xF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_HDTX_CAR << 2), + 0xFF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_PKT_CAR << 2), + 0xF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_AIF_CAR << 2), + 0xF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_CIPHER_CAR << 2), + 0xF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_CRYPTO_CAR << 2), + 0xF); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR + + (SOURCE_CEC_CAR << 2), 3); + + /*init vif */ + /*ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_VIF + +(HSYNC2VSYNC_POL_CTRL<<2), F_HPOL(0) | F_VPOL(0)); */ + + return ret; +} + + +CDN_API_STATUS CDN_API_HDMITX_SetVic_blocking(VIC_MODES vicMode, int bpp, + VIC_PXL_ENCODING_FORMAT format) +{ + CDN_API_STATUS ret; + GENERAL_READ_REGISTER_RESPONSE resp; + unsigned int vsync_lines = vic_table[vicMode][VSYNC]; + unsigned int eof_lines = vic_table[vicMode][TYPE_EOF]; + unsigned int sof_lines = vic_table[vicMode][SOF]; + unsigned int hblank = vic_table[vicMode][H_BLANK]; + unsigned int hactive = vic_table[vicMode][H_TOTAL] - hblank; + unsigned int vblank = vsync_lines + eof_lines + sof_lines; + unsigned int vactive = vic_table[vicMode][V_TOTAL] - vblank; + unsigned int hfront = vic_table[vicMode][FRONT_PORCH]; + unsigned int hback = vic_table[vicMode][BACK_PORCH]; + unsigned int vfront = eof_lines; + unsigned int hsync = hblank - hfront - hback; + unsigned int vsync = vsync_lines; + unsigned int vback = sof_lines; + unsigned int v_h_polarity = ((vic_table[vicMode][HSYNC_POL] == + ACTIVE_LOW) ? 0 : 1) + + ((vic_table[vicMode][VSYNC_POL] == ACTIVE_LOW) ? 0 : 2); + + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (SCHEDULER_H_SIZE << 2), + (hactive << 16) + hblank); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (SCHEDULER_V_SIZE << 2), + (vactive << 16) + vblank); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_SIGNAL_FRONT_WIDTH + << 2), + (vfront << 16) + hfront); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_SIGNAL_SYNC_WIDTH + << 2), + (vsync << 16) + hsync); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_SIGNAL_BACK_WIDTH + << 2), + (vback << 16) + hback); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_VIF + + (HSYNC2VSYNC_POL_CTRL + << 2), + v_h_polarity); + + /* Data Enable is 1 */ + + /*Reset Data Enable */ + cdn_api_general_read_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), &resp); + + /*reset data enable */ + resp.val = resp.val & (~(F_DATA_EN(1))); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + /*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(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + /*set data enable */ + resp.val = resp.val | (F_DATA_EN(1)); + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + + return ret; +} + +CDN_API_STATUS CDN_API_HDMITX_ForceColorDepth_blocking(unsigned char force, + unsigned char val) +{ + unsigned int valToWrite = F_COLOR_DEPTH_VAL(val) | + F_COLOR_DEPTH_FORCE(force); + + return cdn_api_general_write_register_blocking + (ADDR_SOURCE_MHL_HD + + (GCP_FORCE_COLOR_DEPTH_CODING << 2), + valToWrite); +} + +CDN_API_STATUS CDN_API_HDMITX_ReadEvents(uint32_t *events) +{ + CDN_API_STATUS ret; + + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + + internal_tx_mkfullmsg(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; + + ret = internal_test_rx_head(MB_MODULE_ID_HDMI_TX, HDMI_TX_EVENTS); + + if (ret != CDN_OK) + return ret; + + internal_readmsg(1, 4, events); + + return CDN_OK; +} + +CDN_API_STATUS CDN_API_HDMITX_ReadEvents_blocking(uint32_t *events) +{ + internal_block_function(CDN_API_HDMITX_ReadEvents(events)); +} + +CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus(uint8_t *hpd_sts) +{ + CDN_API_STATUS ret; + + if (!state.running) { + if (!internal_apb_available()) + return CDN_BSY; + + /* + * General Module is used here for obtaining HPD State because + * HDMI TX Module is inactive in stand-by mode, thus cannot + * return it. + */ + internal_tx_mkfullmsg(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; + + ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, + GENERAL_GET_HPD_STATE); + + if (ret != CDN_OK) + return ret; + + internal_readmsg(1, 1, hpd_sts); + + return CDN_OK; +} + +CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus_blocking(uint8_t *hpd_sts) +{ + internal_block_function(CDN_API_HDMITX_GetHpdStatus(hpd_sts)); +} diff --git a/drivers/video/imx/hdp/API_HDMITX.h b/drivers/video/imx/hdp/API_HDMITX.h new file mode 100644 index 000000000000..7e910de934cb --- /dev/null +++ b/drivers/video/imx/hdp/API_HDMITX.h @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_HDMITX.h + * + ****************************************************************************** + */ + +#ifndef _API_HDMITX_H_ +# define _API_HDMITX_H_ + +# include "API_General.h" +# include "hdmi.h" +# include "vic_table.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 + */ + unsigned char *buff; + HDMI_I2C_STATUS status; + unsigned short len; + unsigned char slave; + unsigned char 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(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out); +CDN_API_STATUS CDN_API_HDMITX_DDC_READ_blocking(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(HDMITX_TRANS_DATA *data_in, + HDMITX_TRANS_DATA *data_out); +CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE_blocking(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(HDMITX_TRANS_DATA *data_out); +CDN_API_STATUS +CDN_API_HDMITX_DDC_UPDATE_READ_blocking(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(unsigned char block, + unsigned char segment, + HDMITX_TRANS_DATA *data_out); +CDN_API_STATUS CDN_API_HDMITX_READ_EDID_blocking(unsigned char block, + unsigned char 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(HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol, + float character_rate);*/ +CDN_API_STATUS +CDN_API_HDMITX_Set_Mode_blocking(HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol, + unsigned int character_rate); +/** + * \brief init hdmi registers + * \returns status + */ +CDN_API_STATUS CDN_API_HDMITX_Init_blocking(void); + +/** + * \brief change to vid id vicMode + * \returns status + */ +CDN_API_STATUS CDN_API_HDMITX_SetVic_blocking(VIC_MODES vicMode, + 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(unsigned char force, + unsigned char val); + +/** + * \brief send HDMI_TX_TX_READ_EVENTS command + */ +CDN_API_STATUS CDN_API_HDMITX_ReadEvents(uint32_t *events); + +/** + * blocking version of #CDN_API_HDMITX_ReadEvents + */ +CDN_API_STATUS CDN_API_HDMITX_ReadEvents_blocking(uint32_t *events); + +/** + * \brief get current HPD status + */ +CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus(uint8_t *hpd_sts); + +/** + * \brief blocking version of #CDN_API_HDMITX_GetHpdStatus + */ +CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus_blocking(uint8_t *hpd_sts); + +#endif diff --git a/drivers/video/imx/hdp/API_Infoframe.c b/drivers/video/imx/hdp/API_Infoframe.c new file mode 100644 index 000000000000..9fe05aabb5a3 --- /dev/null +++ b/drivers/video/imx/hdp/API_Infoframe.c @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_Infoframe.c + * + ****************************************************************************** + */ + +#include "API_Infoframe.h" +#include "address.h" +#include "source_pif.h" +#include "externs.h" +#ifndef __UBOOT__ +#include +#include +#include +#else +#include +#include +#endif +#include "util.h" + +#define BANK_OFFSET 0x0 + +/* Redefined because of compiler warnings about 32 bit shift left */ +#ifdef F_DATA_WR +#undef F_DATA_WR +#define F_DATA_WR(a_) ((uint32_t)(a_)) +#endif + +static CDN_API_STATUS infoframeSet(unsigned char entry_id, + unsigned char packet_len, + unsigned int *packet, + unsigned char packet_type, + unsigned char active_idle) +{ + unsigned int idx; + unsigned int activeIdleBit = (0 == active_idle) ? 0 : 0x20000; + /*invalidate entry */ + if (cdn_apb_write(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(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(BANK_OFFSET | ADDR_SOURCE_PIF | + (SOURCE_PIF_FIFO1_FLUSH << 2), + F_FIFO1_FLUSH(1))) + return CDN_ERR; + + /*write packet into memory */ + for (idx = 0; idx < packet_len; idx++) + if (cdn_apb_write(BANK_OFFSET | ADDR_SOURCE_PIF | + (SOURCE_PIF_DATA_WR << 2), + F_DATA_WR(packet[idx]))) + return CDN_ERR; + + /*write entry id */ + if (cdn_apb_write(BANK_OFFSET | ADDR_SOURCE_PIF | + (SOURCE_PIF_WR_ADDR << 2), + F_WR_ADDR(entry_id))) + return CDN_ERR; + + /*write request */ + if (cdn_apb_write(BANK_OFFSET | ADDR_SOURCE_PIF | + (SOURCE_PIF_WR_REQ << 2), + F_HOST_WR(1))) + return CDN_ERR; + + /*update entry */ + if (cdn_apb_write(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(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(unsigned char entry_id, + unsigned char packet_len, + unsigned int *packet, + unsigned char packet_type) +{ + return infoframeSet(entry_id, packet_len, packet, packet_type, 1); +} + +CDN_API_STATUS cdn_api_infoframesetnoactiveidle(unsigned char entry_id, + unsigned char packet_len, + unsigned int *packet, + unsigned char packet_type) +{ + return infoframeSet(entry_id, packet_len, packet, packet_type, 0); +} + +CDN_API_STATUS cdn_api_infoframeremove(unsigned char entry_id) +{ + /*invalidate entry */ + if (cdn_apb_write(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(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/video/imx/hdp/API_Infoframe.h b/drivers/video/imx/hdp/API_Infoframe.h new file mode 100644 index 000000000000..6cfde69535f9 --- /dev/null +++ b/drivers/video/imx/hdp/API_Infoframe.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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_Infoframe.h + * + ****************************************************************************** + */ + +#ifndef API_INFOFRAME_H +# define API_INFOFRAME_H + +/** + * \addtogroup INFO_FRAME_API + * \{ + */ + +# include "API_General.h" + +CDN_API_STATUS cdn_api_infoframeset(unsigned char entry_id, + unsigned char packet_len, + unsigned int *packet, + unsigned char packet_type); +CDN_API_STATUS cdn_api_infoframesetnoactiveidle(unsigned char entry_id, + unsigned char packet_len, + unsigned int *packet, + unsigned char packet_type); +CDN_API_STATUS cdn_api_infoframeremove(unsigned char entry_id); + +#endif diff --git a/drivers/video/imx/hdp/Makefile b/drivers/video/imx/hdp/Makefile new file mode 100644 index 000000000000..d704b73201c6 --- /dev/null +++ b/drivers/video/imx/hdp/Makefile @@ -0,0 +1,49 @@ +# +# Copyright 2018 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-$(CONFIG_VIDEO_IMX_HDP_LOAD) += API_General.o util.o test_base_sw.o + +obj-$(CONFIG_VIDEO_IMX8_HDMI) += \ + API_General.o \ + test_base_sw.o \ + API_AVI.o \ + API_Infoframe.o \ + util.o \ + vic_table.o \ + edid_parser.o \ + API_AFE.o \ + API_HDMITX.o \ + API_AFE_t28hpc_hdmitx.o + +# common objects +#obj-y += \ +# API_General.o API_AVI.o API_Infoframe.o \ +# util.o vic_table.o test_base_sw.o \ +# avgen_drv.o edid_parser.o \ +# API_AFE.o + +#DP objects +# API_DPTX.o \ +# API_AFE_mcu2_dp.o\ +# mhdp_firmware.o + +#hdmi objects +#obj-y += \ +# API_HDMITX.o \ +# API_HDCP.o \ +# API_AFE_t28hpc_hdmitx.o +# + +# USE for QM +# blob/API_AFE_mcu1_dp.o +# blob/API_AFE_ss28fdsoi_kiran_hdmitx.o +# blob/ss28fdsoi_hdmitx_table.o +# blob/hdmitx_firmware.o +# blob/mhdp_firmware.o + +# Use for mscale +# API_AFE_mcu2_dp.o () +# API_AFE_t28hpc_hdmitx.c +# diff --git a/drivers/video/imx/hdp/address.h b/drivers/video/imx/hdp/address.h new file mode 100644 index 000000000000..fd8936246bd9 --- /dev/null +++ b/drivers/video/imx/hdp/address.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * + * 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_AFE (0x20000 * 4) +# define ADDR_SOURCD_PHY (0x800) + +#endif diff --git a/drivers/video/imx/hdp/apb_cfg.h b/drivers/video/imx/hdp/apb_cfg.h new file mode 100644 index 000000000000..572ab07b94d9 --- /dev/null +++ b/drivers/video/imx/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-2018 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 /*APB_CFG*/ diff --git a/drivers/video/imx/hdp/avgen.h b/drivers/video/imx/hdp/avgen.h new file mode 100644 index 000000000000..507d851d1e75 --- /dev/null +++ b/drivers/video/imx/hdp/avgen.h @@ -0,0 +1,252 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * This file was auto-generated. Do not edit it manually. + * + ****************************************************************************** + * + * avgen.h + * + ****************************************************************************** + */ + +#ifndef AVGEN_H_ +# define AVGEN_H_ + + +/* register HDMIPOL */ +# define HDMIPOL 0 +# define F_HDMI_V_H_POLARITY(x) (((x) & ((1 << 2) - 1)) << 0) +# define F_HDMI_V_H_POLARITY_RD(x) (((x) & (((1 << 2) - 1) << 0)) >> 0) +# define F_HDMI_BITWIDTH(x) (((x) & ((1 << 2) - 1)) << 2) +# define F_HDMI_BITWIDTH_RD(x) (((x) & (((1 << 2) - 1) << 2)) >> 2) + +/* register HDMI_FRONT_PORCHE_L */ +# define HDMI_FRONT_PORCHE_L 1 +# define F_HDMI_FRONT_PORCHE_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_FRONT_PORCHE_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDFP */ +# define HDFP 2 +# define F_HDMI_FRONT_PORCHE_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_FRONT_PORCHE_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDBP */ +# define HDBP 3 +# define F_HDMI_BACK_PORCHE_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_BACK_PORCHE_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDMI_BACK_PORCHE_H */ +# define HDMI_BACK_PORCHE_H 4 +# define F_HDMI_BACK_PORCHE_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_BACK_PORCHE_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDAS */ +# define HDAS 5 +# define F_HDMI_ACTIVE_SLOT_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_ACTIVE_SLOT_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDMI_ACTIVE_SLOT_H */ +# define HDMI_ACTIVE_SLOT_H 6 +# define F_HDMI_ACTIVE_SLOT_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_ACTIVE_SLOT_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDFL */ +# define HDFL 7 +# define F_HDMI_FRAME_LINES_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_FRAME_LINES_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDMI_FRAME_LINES_H */ +# define HDMI_FRAME_LINES_H 8 +# define F_HDMI_FRAME_LINES_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_FRAME_LINES_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDLW */ +# define HDLW 9 +# define F_HDMI_LINE_WIDTH_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_LINE_WIDTH_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDMI_LINE_WIDTH_H */ +# define HDMI_LINE_WIDTH_H 10 +# define F_HDMI_LINE_WIDTH_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDMI_LINE_WIDTH_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDVL */ +# define HDVL 11 +# define F_HDMI_VSYNC_LINES(x) (((x) & ((1 << 7) - 1)) << 0) +# define F_HDMI_VSYNC_LINES_RD(x) (((x) & (((1 << 7) - 1) << 0)) >> 0) + +/* register HDEL */ +# define HDEL 12 +# define F_HDMI_EOF_LINES(x) (((x) & ((1 << 7) - 1)) << 0) +# define F_HDMI_EOF_LINES_RD(x) (((x) & (((1 << 7) - 1) << 0)) >> 0) + +/* register HDSL */ +# define HDSL 13 +# define F_HDMI_SOF_LINES(x) (((x) & ((1 << 7) - 1)) << 0) +# define F_HDMI_SOF_LINES_RD(x) (((x) & (((1 << 7) - 1) << 0)) >> 0) + +/* register HDCFUPDT */ +# define HDCFUPDT 14 +# define F_HDMI_CODE_FORMAT_UPDT(x) (((x) & ((1 << 6) - 1)) << 0) +# define F_HDMI_CODE_FORMAT_UPDT_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0) + +/* register HDCF */ +# define HDCF 15 +# define F_HDMI_CODE_FORMAT(x) (((x) & ((1 << 6) - 1)) << 0) +# define F_HDMI_CODE_FORMAT_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0) + +/* register HDASPACE */ +# define HDASPACE 16 +# define F_HDASPACE(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_HDASPACE_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register HDMI_3D_MODE */ +# define HDMI_3D_MODE 17 +# define F_HDMI_3D_MODE(x) (((x) & ((1 << 3) - 1)) << 0) +# define F_HDMI_3D_MODE_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0) + +/* register PTRNGENR */ +# define PTRNGENR 18 +# define F_PTRNGENR_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENR_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRNGENR_H */ +# define PTRNGENR_H 19 +# define F_PTRNGENR_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENR_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRNGENG */ +# define PTRNGENG 20 +# define F_PTRNGENG_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENG_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRNEGENG_H */ +# define PTRNEGENG_H 21 +# define F_PTRNGENG_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENG_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRNGENB */ +# define PTRNGENB 22 +# define F_PTRNGENB_L(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENB_L_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRGENB */ +# define PTRGENB 23 +# define F_PTRNGENB_H(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_PTRNGENB_H_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register PTRNGENFF */ +# define PTRNGENFF 30 +# define F_PTRNGENIP(x) (((x) & ((1 << 1) - 1)) << 1) +# define F_PTRNGENIP_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1) + +/* register PGENCTRL */ +# define PGENCTRL 32 +# define F_PGENCF(x) (((x) & ((1 << 6) - 1)) << 1) +# define F_PGENCF_RD(x) (((x) & (((1 << 6) - 1) << 1)) >> 1) +# define F_PTRNGENSTRT(x) (((x) & ((1 << 1) - 1)) << 7) +# define F_PTRNGENSTRT_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7) + +/* register PGENCTRL_H */ +# define PGENCTRL_H 33 +# define F_PTRNGENRST(x) (((x) & ((1 << 1) - 1)) << 0) +# define F_PTRNGENRST_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0) +# define F_PIC_SEL(x) (((x) & ((1 << 3) - 1)) << 1) +# define F_PIC_SEL_RD(x) (((x) & (((1 << 3) - 1) << 1)) >> 1) +# define F_PIC_YCBCR_SEL(x) (((x) & ((1 << 2) - 1)) << 4) +# define F_PIC_YCBCR_SEL_RD(x) (((x) & (((1 << 2) - 1) << 4)) >> 4) + +/* register PGEN_COLOR_BAR_CTRL */ +# define PGEN_COLOR_BAR_CTRL 34 +# define F_PGEN_NUM_BAR(x) (((x) & ((1 << 3) - 1)) << 0) +# define F_PGEN_NUM_BAR_RD(x) (((x) & (((1 << 3) - 1) << 0)) >> 0) + +/* register PGEN_COLOR_BAR_CONTROL_H */ +# define PGEN_COLOR_BAR_CONTROL_H 35 +# define F_PGEN_COLOR_UPDT(x) (((x) & ((1 << 6) - 1)) << 0) +# define F_PGEN_COLOR_UPDT_RD(x) (((x) & (((1 << 6) - 1) << 0)) >> 0) + +/* register GEN_AUDIO_CONTROL */ +# define GEN_AUDIO_CONTROL 36 +# define F_AUDIO_START(x) (((x) & ((1 << 1) - 1)) << 1) +# define F_AUDIO_START_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1) +# define F_AUDIO_RESET(x) (((x) & ((1 << 1) - 1)) << 2) +# define F_AUDIO_RESET_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2) + +/* register SPDIF_CTRL_A */ +# define SPDIF_CTRL_A 37 +# define F_SPDIF_SOURCE_NUM(x) (((x) & ((1 << 4) - 1)) << 0) +# define F_SPDIF_SOURCE_NUM_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0) +# define F_SPDIF_CH_NUM(x) (((x) & ((1 << 4) - 1)) << 4) +# define F_SPDIF_CH_NUM_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4) + +/* register SPDIF_CTRL_A_H */ +# define SPDIF_CTRL_A_H 38 +# define F_SPDIF_SMP_FREQ(x) (((x) & ((1 << 4) - 1)) << 0) +# define F_SPDIF_SMP_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0) +# define F_SPDIF_CLK_ACCUR(x) (((x) & ((1 << 2) - 1)) << 4) +# define F_SPDIF_CLK_ACCUR_RD(x) (((x) & (((1 << 2) - 1) << 4)) >> 4) +# define F_SPDIF_VALID(x) (((x) & ((1 << 1) - 1)) << 6) +# define F_SPDIF_VALID_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6) + +/* register SPDIF_CTRL_B */ +# define SPDIF_CTRL_B 39 +# define F_SPDIF_WORD_LENGTH(x) (((x) & ((1 << 4) - 1)) << 0) +# define F_SPDIF_WORD_LENGTH_RD(x) (((x) & (((1 << 4) - 1) << 0)) >> 0) +# define F_SPDIF_ORG_SMP_FREQ(x) (((x) & ((1 << 4) - 1)) << 4) +# define F_SPDIF_ORG_SMP_FREQ_RD(x) (((x) & (((1 << 4) - 1) << 4)) >> 4) + +/* register SPDIF_CTRL_B_H */ +# define SPDIF_CTRL_B_H 40 +# define F_CATEGORY_MODE(x) (((x) & ((1 << 8) - 1)) << 0) +# define F_CATEGORY_MODE_RD(x) (((x) & (((1 << 8) - 1) << 0)) >> 0) + +/* register AUDIO_DIV_EN */ +# define AUDIO_DIV_EN 45 +# define F_AGEN_60958_I2S(x) (((x) & ((1 << 1) - 1)) << 1) +# define F_AGEN_60958_I2S_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1) +# define F_AGEN_PRL_SUBFRAME(x) (((x) & ((1 << 1) - 1)) << 2) +# define F_AGEN_PRL_SUBFRAME_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2) +# define F_AGEN_SAMPLES_DATA(x) (((x) & ((1 << 1) - 1)) << 3) +# define F_AGEN_SAMPLES_DATA_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3) + +#endif /*AVGEN */ diff --git a/drivers/video/imx/hdp/avgen_drv.c b/drivers/video/imx/hdp/avgen_drv.c new file mode 100644 index 000000000000..171c5f94653d --- /dev/null +++ b/drivers/video/imx/hdp/avgen_drv.c @@ -0,0 +1,305 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * avgen_drv.c + * + ****************************************************************************** + */ + +#include "mhl_hdtx_top.h" +#include "address.h" +#include "avgen.h" +#include "avgen_drv.h" +#include "util.h" +#include "externs.h" + +#define ADDR_AVGEN 0x80000 + +CDN_API_STATUS CDN_API_AVGEN_Set(VIC_MODES vicMode, CDN_PROTOCOL_TYPE protocol, + VIC_PXL_ENCODING_FORMAT format) +{ + /*CDN_API_STATUS ret; */ + /*GENERAL_Read_Register_response resp; */ + unsigned int pixelClockFreq = CDN_API_Get_PIXEL_FREQ_KHZ_ClosetVal + (vic_table[vicMode][PIXEL_FREQ_KHZ], protocol); + unsigned int v_h_polarity = + ((vic_table[vicMode][HSYNC_POL] == ACTIVE_LOW) ? 0 : 1) + + ((vic_table[vicMode][VSYNC_POL] == ACTIVE_LOW) ? 0 : 2); + unsigned int front_porche_l = vic_table[vicMode][FRONT_PORCH] - 256 * + ((unsigned int)vic_table[vicMode][FRONT_PORCH] / 256); + unsigned int front_porche_h = vic_table[vicMode][FRONT_PORCH] / 256; + unsigned int back_porche_l = vic_table[vicMode][BACK_PORCH] - 256 * + ((unsigned int)vic_table[vicMode][BACK_PORCH] / 256); + unsigned int back_porche_h = vic_table[vicMode][BACK_PORCH] / 256; + unsigned int active_slot_l = vic_table[vicMode][H_BLANK] - 256 * + ((unsigned int)vic_table[vicMode][H_BLANK] / 256); + unsigned int active_slot_h = vic_table[vicMode][H_BLANK] / 256; + unsigned int frame_lines_l = vic_table[vicMode][V_TOTAL] - 256 * + ((unsigned int)vic_table[vicMode][V_TOTAL] / 256); + unsigned int frame_lines_h = vic_table[vicMode][V_TOTAL] / 256; + unsigned int line_width_l = vic_table[vicMode][H_TOTAL] - 256 * + ((unsigned int)vic_table[vicMode][H_TOTAL] / 256); + unsigned int line_width_h = vic_table[vicMode][H_TOTAL] / 256; + unsigned int vsync_lines = vic_table[vicMode][VSYNC]; + unsigned int eof_lines = vic_table[vicMode][TYPE_EOF]; + unsigned int sof_lines = vic_table[vicMode][SOF]; + unsigned int interlace_progressive = + (vic_table[vicMode][I_P] == INTERLACED) ? 2 : 0; + unsigned int set_vif_clock = 0; + + /*needed for HDMI /////////////////////////////// */ + /*unsigned int hblank = vic_table[vicMode][H_BLANK]; */ + /*unsigned int hactive = vic_table[vicMode][H_TOTAL]-hblank; */ + /*unsigned int vblank = vsync_lines+eof_lines+sof_lines; */ + /*unsigned int vactive = vic_table[vicMode][V_TOTAL]-vblank; */ + /*unsigned int hfront = vic_table[vicMode][FRONT_PORCH]; */ + /*unsigned int hback = vic_table[vicMode][BACK_PORCH]; */ + /*unsigned int vfront = eof_lines; */ + /*unsigned int hsync = hblank-hfront-hback; */ + /*unsigned int vsync = vsync_lines; */ + /*unsigned int vback = sof_lines; */ + unsigned int set_CLK_SEL = 0; + unsigned int set_REF_CLK_SEL = 0; + unsigned int set_pll_CLK_IN = 0; + unsigned int set_pll_clkfbout_l = 0; + unsigned int set_pll_clkfbout_h = 0; + unsigned int set_pll_CLKOUT5_L = 0; + unsigned int set_pll_CLKOUT5_H = 0; + unsigned int set_pll2_CLKIN = 0; + unsigned int set_pll2_CLKFBOUT_L = 0; + unsigned int set_pll2_CLKFBOUT_H = 0; + unsigned int set_pll2_CLKOUT5_L = 0; + unsigned int set_pll2_CLKOUT5_H = 0; + /*///////////////////////////////////////////////// */ + + cdn_apb_write(0x1c00C6 << 2, + (int)(vic_table[vicMode][PIXEL_FREQ_KHZ] * 1000)); + cdn_apb_write(0x1c00C6 << 2, (int)(pixelClockFreq)); + + if ((int)(pixelClockFreq) == 25) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 4; + set_REF_CLK_SEL = 0; + set_pll_CLK_IN = 65; + set_pll_clkfbout_l = 4292; + set_pll_clkfbout_h = 128; + set_pll_CLKOUT5_L = 4422; + set_pll_CLKOUT5_H = 128; + set_pll2_CLKIN = 12289; + set_pll2_CLKFBOUT_L = 4356; + set_pll2_CLKFBOUT_H = 0; + set_pll2_CLKOUT5_L = 4552; + set_pll2_CLKOUT5_H = 128; + } else { + set_vif_clock = 0x300; + } + } else if ((int)pixelClockFreq == 27000) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 5; + set_REF_CLK_SEL = 0; + set_pll_CLK_IN = 49217; + set_pll_clkfbout_l = 4226; + set_pll_clkfbout_h = 0; + set_pll_CLKOUT5_L = 4422; + set_pll_CLKOUT5_H = 128; + } else { + set_vif_clock = 0x301; + } + } else if ((int)pixelClockFreq == 54000) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 5; + set_REF_CLK_SEL = 0; + set_pll_CLK_IN = 4096; + set_pll_clkfbout_l = 4226; + set_pll_clkfbout_h = 0; + set_pll_CLKOUT5_L = 4422; + set_pll_CLKOUT5_H = 128; + } else { + set_vif_clock = 0x302; + } + } else if (pixelClockFreq == 74250) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 1; + set_pll_CLK_IN = 74; + } else { + set_vif_clock = 0x303; + } + } else if (pixelClockFreq == 148500) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 0; + set_pll_CLK_IN = 148; + } else { + set_vif_clock = 0x304; + } + } else if ((int)pixelClockFreq == 108000) { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 5; + set_REF_CLK_SEL = 2; + set_pll_CLK_IN = 8258; + set_pll_clkfbout_l = 4616; + set_pll_clkfbout_h = 0; + set_pll_CLKOUT5_L = 4422; + set_pll_CLKOUT5_H = 128; + } else { + set_vif_clock = 0x305; + } + } else { + if (protocol == CDN_HDMITX_TYPHOON) { + set_CLK_SEL = 1; + set_pll_CLK_IN = pixelClockFreq; + } else { + set_vif_clock = 0; + } + } + unsigned int start_pgen = 128; + /*unsigned int temp; */ + if (protocol == CDN_HDMITX_TYPHOON) { + if (cdn_apb_write(0x0c0001 << 2, + ((0) + (2 * set_CLK_SEL) + (16 * 0) + + (32 * 0) + (64 * 3) + (65536 * 3) + + (1048576 * set_REF_CLK_SEL)))) + return CDN_ERR; + if (cdn_apb_write(0x1c00C6 << 2, set_pll_CLK_IN)) + return CDN_ERR; + if (cdn_apb_write(0x1c00CC << 2, set_pll_clkfbout_l)) + return CDN_ERR; + if (cdn_apb_write(0x1c00CD << 2, set_pll_clkfbout_h)) + return CDN_ERR; + if (cdn_apb_write(0x1c00CE << 2, set_pll_CLKOUT5_L)) + return CDN_ERR; + if (cdn_apb_write(0x1c00CF << 2, set_pll_CLKOUT5_H)) + return CDN_ERR; + if (cdn_apb_write(0x1c0086 << 2, set_pll2_CLKIN)) + return CDN_ERR; + if (cdn_apb_write(0x1c008C << 2, set_pll2_CLKFBOUT_L)) + return CDN_ERR; + if (cdn_apb_write(0x1c008D << 2, set_pll2_CLKFBOUT_H)) + return CDN_ERR; + if (cdn_apb_write(0x1c008E << 2, set_pll2_CLKOUT5_L)) + return CDN_ERR; + if (cdn_apb_write(0x1c008F << 2, set_pll2_CLKOUT5_H)) + return CDN_ERR; + if (cdn_apb_write(0x0c0001 << 2, + ((1) + (2 * set_CLK_SEL) + (16 * 0) + + (32 * 0) + (64 * 3) + (65536 * 3) + + (1048576 * set_REF_CLK_SEL)))) + return CDN_ERR; + } + + if (cdn_apb_write((ADDR_AVGEN + HDMIPOL) << 2, v_h_polarity)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDMI_FRONT_PORCHE_L) << 2, + front_porche_l)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDFP) << 2, front_porche_h)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDBP) << 2, back_porche_l)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDMI_BACK_PORCHE_H) << 2, + back_porche_h)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDAS) << 2, active_slot_l)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDMI_ACTIVE_SLOT_H) << 2, + active_slot_h)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDFL) << 2, frame_lines_l)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDMI_FRAME_LINES_H) << 2, + frame_lines_h)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDLW) << 2, line_width_l)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDMI_LINE_WIDTH_H) << 2, line_width_h)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDVL) << 2, vsync_lines)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDEL) << 2, eof_lines)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + HDSL) << 2, sof_lines)) + return CDN_ERR; + if (cdn_apb_write((ADDR_AVGEN + PTRNGENFF) << 2, interlace_progressive)) + return CDN_ERR; + + if (protocol == CDN_HDMITX_TYPHOON) { + switch (format) { + case PXL_RGB: + + if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2, + F_PIC_SEL(1) | F_PIC_YCBCR_SEL(0))) + return CDN_ERR; + break; + + case YCBCR_4_4_4: + if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2, + F_PIC_SEL(2) | F_PIC_YCBCR_SEL(0))) + return CDN_ERR; + + break; + + case YCBCR_4_2_2: + if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2, + F_PIC_SEL(2) | F_PIC_YCBCR_SEL(1))) + return CDN_ERR; + + break; + + case YCBCR_4_2_0: + if (cdn_apb_write((ADDR_AVGEN + PGENCTRL_H) << 2, + F_PIC_SEL(2) | F_PIC_YCBCR_SEL(2))) + return CDN_ERR; + + break; + case Y_ONLY: + /*not exist in hdmi */ + break; + } + } else { + if (set_vif_clock != 0) + if (cdn_apb_write(0xC0006 << 2, set_vif_clock)) + return CDN_ERR; + } + + if (cdn_apb_write((ADDR_AVGEN + PGENCTRL) << 2, start_pgen)) + return CDN_ERR; + + return CDN_OK; +} diff --git a/drivers/video/imx/hdp/avgen_drv.h b/drivers/video/imx/hdp/avgen_drv.h new file mode 100644 index 000000000000..56473d738d0d --- /dev/null +++ b/drivers/video/imx/hdp/avgen_drv.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * avgen_drv.h + * + ****************************************************************************** + */ + +#ifndef AVGEN_DRV_H_ +# define AVGEN_DRV_H_ + +#ifndef __UBOOT__ +# include +#else +#include +#endif + +# include "vic_table.h" +# include "API_General.h" +# include "defs.h" + +/** + * \brief set avgen according to mode and vic table, user that doesnt have + * cadence AVGEN, need to implement this function on user + * platform + */ +CDN_API_STATUS CDN_API_AVGEN_Set(VIC_MODES vicMode, CDN_PROTOCOL_TYPE protocol, + VIC_PXL_ENCODING_FORMAT format); + +#endif diff --git a/drivers/video/imx/hdp/defs.h b/drivers/video/imx/hdp/defs.h new file mode 100644 index 000000000000..12ad806aab29 --- /dev/null +++ b/drivers/video/imx/hdp/defs.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright (C) 2015-2016 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * defs.h + * + ****************************************************************************** + */ + +#ifndef _DEFS_H_ +#define _DEFS_H_ + +typedef enum { + CDN_DPTX , + CDN_HDMITX_TYPHOON, + CDN_HDMITX_KIRAN, +} CDN_PROTOCOL_TYPE; + +#endif /*_DEFS_H_ */ diff --git a/drivers/video/imx/hdp/edid_parser.c b/drivers/video/imx/hdp/edid_parser.c new file mode 100644 index 000000000000..24aa7397910e --- /dev/null +++ b/drivers/video/imx/hdp/edid_parser.c @@ -0,0 +1,617 @@ +/****************************************************************************** + * + * Copyright (C) 2015-2016 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * edid_parser.c + * + ****************************************************************************** + */ + +#include "edid_parser.h" + +static EDID_PARSER_RESULT edid_parse_dtd(S_DTD_DATA *descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_DTD; + descriptor->header.tag = 0; + + descriptor->pixel_clock = raw_data[raw_data_index]; + descriptor->pixel_clock += + (unsigned short)raw_data[raw_data_index + 1] << 8; + + descriptor->horizontal_addressable_video = raw_data[raw_data_index + 2]; + descriptor->horizontal_addressable_video += + ((unsigned short)raw_data[raw_data_index + 4] & 0xF0) << 4; + descriptor->horizontal_blanking = raw_data[raw_data_index + 3]; + descriptor->horizontal_blanking += + ((unsigned short)raw_data[raw_data_index + 4] & 0x0F) << 8; + + descriptor->vertical_addressable_video = raw_data[raw_data_index + 5]; + descriptor->vertical_addressable_video += + ((unsigned short)raw_data[raw_data_index + 7] & 0xF0) << 4; + descriptor->vertical_blanking = raw_data[raw_data_index + 6]; + descriptor->vertical_blanking += + ((unsigned short)raw_data[raw_data_index + 7] & 0x0F) << 8; + + descriptor->horizontal_front_porch = raw_data[raw_data_index + 8]; + descriptor->horizontal_front_porch += + ((unsigned short)raw_data[raw_data_index + 11] & 0xC0) << 2; + descriptor->horizontal_sync_pulse_width = raw_data[raw_data_index + 9]; + descriptor->horizontal_sync_pulse_width += + ((unsigned short)raw_data[raw_data_index + 11] & 0x30) << 4; + + descriptor->vertical_front_porch = + (raw_data[raw_data_index + 10] & 0xF0) >> 4; + descriptor->vertical_front_porch += + (raw_data[raw_data_index + 11] & 0x0C) << 2; + descriptor->vertical_sync_pulse_width = + raw_data[raw_data_index + 10] & 0x0F; + descriptor->vertical_sync_pulse_width += + (raw_data[raw_data_index + 11] & 0x03) << 4; + + descriptor->horizontal_addressable_video_image_size = + raw_data[raw_data_index + 12]; + descriptor->horizontal_addressable_video_image_size += + ((unsigned short)raw_data[raw_data_index + 14] & 0xF0) << 4; + descriptor->vertical_addressable_video_image_size = + raw_data[raw_data_index + 13]; + descriptor->vertical_addressable_video_image_size += + ((unsigned short)raw_data[raw_data_index + 14] & 0x0F) << 8; + + descriptor->horizontal_border = raw_data[raw_data_index + 15]; + descriptor->vertical_border = raw_data[raw_data_index + 16]; + + descriptor->signal_features = raw_data[raw_data_index + 17]; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_serial_number(S_SERIAL_NUMBER_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + descriptor->header.type = DESCRIPTOR_TYPE_SERIAL_NUMBER; + descriptor->header.tag = 0xFF; + + int idx; + for (idx = 0; idx < 13; idx++) + descriptor->serial_number[idx] = + raw_data[raw_data_index + 5 + idx]; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_data_string(S_DATA_STRING_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + descriptor->header.type = DESCRIPTOR_TYPE_DATA_STRING; + descriptor->header.tag = 0xFE; + int idx; + for (idx = 0; idx < 13; idx++) + descriptor->data_string[idx] = + raw_data[raw_data_index + 5 + idx]; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_range_limits(S_RANGE_LIMITS_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_RANGE_LIMITS; + descriptor->header.tag = 0xFD; + + descriptor->offset_flags = raw_data[raw_data_index + 4]; + descriptor->min_vertical_rate = raw_data[raw_data_index + 5]; + descriptor->max_vertical_rate = raw_data[raw_data_index + 6]; + descriptor->min_horizontal_rate = raw_data[raw_data_index + 7]; + descriptor->max_horizontal_rate = raw_data[raw_data_index + 8]; + descriptor->max_pixel_clock = raw_data[raw_data_index + 9]; + + switch (raw_data[raw_data_index + 10]) { + case 0x00: + descriptor->type = VIDEO_TIMING_DEFAULT_GTF; + break; + case 0x01: + descriptor->type = VIDEO_TIMING_RANGE_LIMITS_ONLY; + break; + case 0x02: + descriptor->type = VIDEO_TIMING_SECONDARY_GTF; + S_RANGE_LIMITS_VIDEO_TIMING_SECONDARY_GTF *timing_type_gtf = + (S_RANGE_LIMITS_VIDEO_TIMING_SECONDARY_GTF *) + descriptor->suport_flags; + timing_type_gtf->start_break_frequency = + raw_data[raw_data_index + 12]; + timing_type_gtf->c = raw_data[raw_data_index + 13]; + timing_type_gtf->m = raw_data[raw_data_index + 14]; + timing_type_gtf->m += + (unsigned short)raw_data[raw_data_index + 15] << 8; + timing_type_gtf->k = raw_data[raw_data_index + 16]; + timing_type_gtf->j = raw_data[raw_data_index + 17]; + break; + case 0x04: + descriptor->type = VIDEO_TIMING_CVT; + S_RANGE_LIMITS_VIDEO_TIMING_CVT *timing_type_cvt = + (S_RANGE_LIMITS_VIDEO_TIMING_CVT *)descriptor-> + suport_flags; + timing_type_cvt->cvt_version = raw_data[raw_data_index + 11]; + timing_type_cvt->additional_pixel_clock_precision = + raw_data[raw_data_index + 12] >> 2; + timing_type_cvt->max_active_pixels = + raw_data[raw_data_index + 13]; + timing_type_cvt->max_active_pixels += + (unsigned short)(raw_data[raw_data_index + 12] & 0x03) + << 8; + timing_type_cvt->supported_ar = + raw_data[raw_data_index + 14] >> 3; + timing_type_cvt->preferred_ar = + raw_data[raw_data_index + 15] >> 5; + timing_type_cvt->blanking_support = + (raw_data[raw_data_index + 15] & 0x18) >> 3; + timing_type_cvt->supported_scalling = + raw_data[raw_data_index + 16] >> 4; + timing_type_cvt->preferred_vertical_refresh_rate = + raw_data[raw_data_index + 17]; + break; + } + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_product_name(S_PRODUCT_NAME_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_PRODUCT_NAME; + descriptor->header.tag = 0xFC; + int idx; + for (idx = 0; idx < 13; idx++) + descriptor->product_name[idx] = + raw_data[raw_data_index + 5 + idx]; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_color_point(S_COLOR_POINT_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_COLOR_POINT; + descriptor->header.tag = 0xFB; + descriptor->white_point_index_1 = raw_data[raw_data_index + 5]; + descriptor->white_x_1 = (raw_data[raw_data_index + 6] & 0x0C) >> 2; + descriptor->white_x_1 += + (unsigned short)raw_data[raw_data_index + 7] << 2; + descriptor->white_y_1 = raw_data[raw_data_index + 6] & 0x03; + descriptor->white_y_1 += + (unsigned short)raw_data[raw_data_index + 8] << 2; + descriptor->gamma_1 = raw_data[raw_data_index + 9]; + + descriptor->white_point_index_2 = raw_data[raw_data_index + 10]; + descriptor->white_x_2 = (raw_data[raw_data_index + 11] & 0x0C) >> 2; + descriptor->white_x_2 += + (unsigned short)raw_data[raw_data_index + 12] << 2; + descriptor->white_y_2 = raw_data[raw_data_index + 11] & 0x03; + descriptor->white_y_2 += + (unsigned short)raw_data[raw_data_index + 13] << 2; + descriptor->gamma_2 = raw_data[raw_data_index + 14]; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_standard_timing(S_STANDARD_TIMING_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_STANDARD_TIMING; + descriptor->header.tag = 0xFA; + int idx; + for (idx = 0; idx < 6; idx++) { + descriptor->standard_timings[idx] = + raw_data[raw_data_index + 5 + 2 * idx]; + descriptor->standard_timings[idx] += + (unsigned short)raw_data[raw_data_index + 5 + 2 * idx + + 1]; + } + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_color_management(S_COLOR_MANAGEMENT_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_COLOR_MANAGEMENT; + descriptor->header.tag = 0xF9; + + descriptor->version = raw_data[raw_data_index + 5]; + + descriptor->red_a3 = raw_data[raw_data_index + 6]; + descriptor->red_a3 += (unsigned short)raw_data[raw_data_index + 7] << 8; + descriptor->red_a2 = raw_data[raw_data_index + 8]; + descriptor->red_a2 += (unsigned short)raw_data[raw_data_index + 9] << 8; + + descriptor->green_a3 = raw_data[raw_data_index + 10]; + descriptor->green_a3 += + (unsigned short)raw_data[raw_data_index + 11] << 8; + descriptor->green_a2 = raw_data[raw_data_index + 12]; + descriptor->green_a2 += + (unsigned short)raw_data[raw_data_index + 13] << 8; + + descriptor->blue_a3 = raw_data[raw_data_index + 14]; + descriptor->blue_a3 += + (unsigned short)raw_data[raw_data_index + 15] << 8; + descriptor->blue_a2 = raw_data[raw_data_index + 16]; + descriptor->blue_a2 += + (unsigned short)raw_data[raw_data_index + 17] << 8; + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_cvt_timing_codes(S_CVT_TIMING_CODES_DATA * + descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_CVT_TIMING_CODES; + descriptor->header.tag = 0xF8; + descriptor->version = raw_data[raw_data_index + 5]; + + int idx; + for (idx = 0; idx < 4; idx++) { + descriptor->addressable_lines[idx] = + raw_data[raw_data_index + 6 + idx * 3]; + descriptor->addressable_lines[idx] += + (unsigned short)(raw_data[raw_data_index + 7 + idx * 3] + & 0xF0) << 4; + descriptor->aspect_ratio[idx] = + (raw_data[raw_data_index + 7 + idx * 3] & 0x0C) >> 2; + descriptor->preferred_vertical_rate[idx] = + (raw_data[raw_data_index + 8 + idx * 3] & 0x60) >> 5; + descriptor->supported_vertical_rate_and_blanking[idx] = + raw_data[raw_data_index + 8 + idx * 3] & 0x1F; + } + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT +edid_parse_established_timings_3(S_ESTABLISHED_TIMINGS_3_DATA *descriptor, + unsigned char *raw_data) +{ + unsigned int raw_data_index = 0; + + descriptor->header.type = DESCRIPTOR_TYPE_ESTABLISHED_TIMINGS_3; + descriptor->header.tag = 0xF7; + descriptor->version = raw_data[raw_data_index + 5]; + int idx; + for (idx = 0; idx < 6; idx++) { + descriptor->established_timings[idx] = + raw_data[raw_data_index + 6 + idx]; + } + + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT edid_parse_dummy(S_DUMMY_DATA *descriptor, + unsigned char *raw_data) +{ + descriptor->header.type = DESCRIPTOR_TYPE_DUMMY; + descriptor->header.tag = 0x10; + return EDID_PARSER_SUCCESS; +} + +static EDID_PARSER_RESULT +edid_parse_manufacturer_specific(S_MANUFACTURER_SPECIFIC_DATA *descriptor, + unsigned char *raw_data, unsigned char tag) +{ + descriptor->header.type = DESCRIPTOR_TYPE_MANUFACTURER_SPECIFIC; + descriptor->header.tag = tag; + + return EDID_PARSER_SUCCESS; +} + +EDID_PARSER_RESULT edid_parse(S_EDID_DATA *edid, unsigned char *raw_data, + unsigned int len) +{ + unsigned int raw_data_index = 0; + unsigned char sum = 0; + /*CHECK SUM OF BYTES IN BLOCK0 */ + for (raw_data_index = 0; raw_data_index < EDID_LENGTH; raw_data_index++) + sum += raw_data[raw_data_index]; + + if (sum != 0) + return EDID_PARSER_ERROR; + + /*READ HEADER */ + for (raw_data_index = 0; raw_data_index < EDID_HEADER_LENGTH; + raw_data_index++) + edid->header[raw_data_index] = raw_data[raw_data_index]; + + /*READ VENDOR & PRODUCT IDENTIFICATION */ + /*manufacturer name */ + edid->manufacturer_name[0] = ((raw_data[8] & 0x7C) >> 2) + 0x40; + edid->manufacturer_name[1] = + ((raw_data[8] & 0x03) << 3) + ((raw_data[9] & 0xE0) >> 5) + + 0x40; + edid->manufacturer_name[2] = ((raw_data[9] & 0x1F)) + 0x40; + edid->manufacturer_name[3] = 0; + + /*product code */ + edid->product_code = (raw_data[10]); + edid->product_code += ((unsigned short)raw_data[11]) << 8; + + /*serial number */ + edid->serial_number = raw_data[12]; + edid->serial_number += (unsigned int)raw_data[13] << 8; + edid->serial_number += (unsigned int)raw_data[14] << 16; + edid->serial_number += (unsigned int)raw_data[15] << 24; + + /*week of manufacture */ + edid->week = raw_data[16]; + + /*year of manufacture */ + edid->year = raw_data[17]; + + /*EDID STRUCTURE VERSION & REVISION */ + edid->edid_version = ((unsigned short)raw_data[18] << 8) + raw_data[19]; + + /*BASIC DISPLAY PARAMETERS AND FEATURES */ + /*video input definition */ + edid->video_input_definition = raw_data[20]; + + /*horizontal screen size */ + edid->horizontal_size = raw_data[21]; + + /*vertical screen size */ + edid->vertical_size = raw_data[22]; + + /*display transfer characteristic */ + edid->gamma = raw_data[23]; + + /*feature support */ + edid->feature_support = raw_data[24]; + + /*COLOR CHARACTERISTIC */ + /*red */ + edid->chromacity_coorditates_red_x = (raw_data[25] & 0xC0) >> 6; + edid->chromacity_coorditates_red_x += (unsigned short)raw_data[27] << 2; + edid->chromacity_coorditates_red_y = (raw_data[25] & 0x30) >> 4; + edid->chromacity_coorditates_red_y += (unsigned short)raw_data[28] << 2; + + /*green */ + edid->chromacity_coorditates_green_x = (raw_data[25] & 0x0C) >> 2; + edid->chromacity_coorditates_green_x += + (unsigned short)raw_data[29] << 2; + edid->chromacity_coorditates_green_y = (raw_data[25] & 0x03); + edid->chromacity_coorditates_green_y += + (unsigned short)raw_data[30] << 2; + + /*blue */ + edid->chromacity_coorditates_blue_x = (raw_data[26] & 0xC0) >> 6; + edid->chromacity_coorditates_blue_x += + (unsigned short)raw_data[31] << 2; + edid->chromacity_coorditates_blue_y = (raw_data[26] & 0x30) >> 4; + edid->chromacity_coorditates_blue_y += + (unsigned short)raw_data[32] << 2; + + /*blue */ + edid->chromacity_coorditates_white_x = (raw_data[26] & 0x0C) >> 2; + edid->chromacity_coorditates_white_x += + (unsigned short)raw_data[33] << 2; + edid->chromacity_coorditates_white_y = (raw_data[26] & 0x03); + edid->chromacity_coorditates_white_y += + (unsigned short)raw_data[34] << 2; + + /*ESTABLISHED TIMINGS */ + edid->established_timing_1 = raw_data[35]; + edid->established_timing_2 = raw_data[36]; + edid->manufacturer_timing = raw_data[37]; + + /*STANDARD TIMINGS */ + for (raw_data_index = 0; raw_data_index < 8; raw_data_index++) { + edid->standard_timings[raw_data_index] = + raw_data[38 + (2 * raw_data_index)]; + edid->standard_timings[raw_data_index] += + (unsigned short)raw_data[38 + (2 * raw_data_index + 1)]; + } + /*extensions */ + edid->extensions = raw_data[126]; + + /*DESCRIPTORS */ + unsigned int descriptor_index; + raw_data_index = 54; + for (descriptor_index = 0; descriptor_index < 4; descriptor_index++) { + if (raw_data[raw_data_index] == 0 && + raw_data[raw_data_index] == 0) { + /*display descriptor found */ + unsigned char tag = raw_data[raw_data_index + 3]; + if (tag == 0xFF) { + /*display product serial number */ + S_SERIAL_NUMBER_DATA *descriptor = + (S_SERIAL_NUMBER_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_serial_number + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xFE) { + /*alphanumeric data string */ + S_DATA_STRING_DATA *descriptor = + (S_DATA_STRING_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_data_string + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xFD) { + /*display range limits */ + S_RANGE_LIMITS_DATA *descriptor = + (S_RANGE_LIMITS_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_range_limits + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xFC) { + /*display product name */ + S_PRODUCT_NAME_DATA *descriptor = + (S_PRODUCT_NAME_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_product_name + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xFB) { + /*color point data */ + S_COLOR_POINT_DATA *descriptor = + (S_COLOR_POINT_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_color_point + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xFA) { + /*standard timing identifications */ + S_STANDARD_TIMING_DATA *descriptor = + (S_STANDARD_TIMING_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_standard_timing + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xF9) { + /*display color management (DCM) */ + S_COLOR_MANAGEMENT_DATA *descriptor = + (S_COLOR_MANAGEMENT_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_color_management + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xF8) { + /*CVT 3 byte timing codes */ + S_CVT_TIMING_CODES_DATA *descriptor = + (S_CVT_TIMING_CODES_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_cvt_timing_codes + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0xF7) { + /*established timings III */ + S_ESTABLISHED_TIMINGS_3_DATA *descriptor = + (S_ESTABLISHED_TIMINGS_3_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_established_timings_3 + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag == 0x10) { + /*dummy */ + S_DUMMY_DATA *descriptor = + (S_DUMMY_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_dummy + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + + } else if (tag <= 0x0F) { + /*manufacturer specific data */ + S_MANUFACTURER_SPECIFIC_DATA *descriptor = + (S_MANUFACTURER_SPECIFIC_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_manufacturer_specific + (descriptor, raw_data + raw_data_index, + tag) != EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + } + } else { + /*detailed timing definition */ + S_DTD_DATA *descriptor = + (S_DTD_DATA *)edid-> + descriptors[descriptor_index]; + if (edid_parse_dtd + (descriptor, + raw_data + raw_data_index) != + EDID_PARSER_SUCCESS) + return EDID_PARSER_ERROR; + } + raw_data_index += 18; + } + + return EDID_PARSER_SUCCESS; +} diff --git a/drivers/video/imx/hdp/edid_parser.h b/drivers/video/imx/hdp/edid_parser.h new file mode 100644 index 000000000000..13eb0b1882bc --- /dev/null +++ b/drivers/video/imx/hdp/edid_parser.h @@ -0,0 +1,297 @@ +/****************************************************************************** + * + * Copyright (C) 2015-2016 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * edid_parser.h + * + ****************************************************************************** + */ + +#ifndef EDID_PARSER_H +#define EDID_PARSER_H + +#define MAX_DESCRIPTOR_LENGTH 36 +#define MAX_RANGE_LIMITS_VIDEO_TIMING_LENGTH 12 +#define EDID_HEADER_LENGTH 8 +#define EDID_LENGTH 128 + +typedef enum { + EDID_PARSER_SUCCESS, + EDID_PARSER_ERROR, +} EDID_PARSER_RESULT; + +typedef enum { + DESCRIPTOR_TYPE_DTD, + DESCRIPTOR_TYPE_SERIAL_NUMBER, + DESCRIPTOR_TYPE_DATA_STRING, + DESCRIPTOR_TYPE_RANGE_LIMITS, + DESCRIPTOR_TYPE_PRODUCT_NAME, + DESCRIPTOR_TYPE_COLOR_POINT, + DESCRIPTOR_TYPE_STANDARD_TIMING, + DESCRIPTOR_TYPE_COLOR_MANAGEMENT, + DESCRIPTOR_TYPE_CVT_TIMING_CODES, + DESCRIPTOR_TYPE_ESTABLISHED_TIMINGS_3, + DESCRIPTOR_TYPE_DUMMY, + DESCRIPTOR_TYPE_MANUFACTURER_SPECIFIC +} EDID_DESCRIPTOR_TYPE; + +typedef enum { + VIDEO_TIMING_DEFAULT_GTF, + VIDEO_TIMING_RANGE_LIMITS_ONLY, + VIDEO_TIMING_SECONDARY_GTF, + VIDEO_TIMING_CVT, +} RANGE_LIMITS_VIDEO_TIMING_TYPE; + +/** + * \brief Common descriptor header structure + */ +typedef struct { + EDID_DESCRIPTOR_TYPE type; + unsigned char tag; + +} S_DESCRIPTOR_HEADER_DATA; +/** + * \brief Detailed Timing Descriptor (DTD) structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned short pixel_clock; + unsigned short horizontal_addressable_video; + unsigned short horizontal_blanking; + unsigned short vertical_addressable_video; + unsigned short vertical_blanking; + unsigned short horizontal_front_porch; + unsigned short horizontal_sync_pulse_width; + unsigned short vertical_front_porch; + unsigned short vertical_sync_pulse_width; + unsigned short horizontal_addressable_video_image_size; + unsigned short vertical_addressable_video_image_size; + unsigned char horizontal_border; + unsigned char vertical_border; + unsigned char signal_features; +} S_DTD_DATA; + +/** + * \brief Serial Number Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char serial_number[13]; + +} S_SERIAL_NUMBER_DATA; + +/** + * \brief Data String Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + char data_string[13]; + +} S_DATA_STRING_DATA; + +/** + * \brief Range Limits Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char offset_flags; + unsigned char min_vertical_rate; + unsigned char max_vertical_rate; + unsigned char min_horizontal_rate; + unsigned char max_horizontal_rate; + unsigned char max_pixel_clock; + RANGE_LIMITS_VIDEO_TIMING_TYPE type; + unsigned char suport_flags[MAX_RANGE_LIMITS_VIDEO_TIMING_LENGTH]; +} S_RANGE_LIMITS_DATA; + +/** + * \brief Range Limits Secondary GTF Flags structure + */ +typedef struct { + unsigned char start_break_frequency; + unsigned char c; + unsigned short m; + unsigned char k; + unsigned char j; + +} S_RANGE_LIMITS_VIDEO_TIMING_SECONDARY_GTF; + +/** + * \brief Range Limits CVT Flags structure + */ +typedef struct { + unsigned char cvt_version; + unsigned char additional_pixel_clock_precision; + unsigned short max_active_pixels; + unsigned char supported_ar; + unsigned char preferred_ar; + unsigned char blanking_support; + unsigned char supported_scalling; + unsigned char preferred_vertical_refresh_rate; +} S_RANGE_LIMITS_VIDEO_TIMING_CVT; + +/** + * \brief Product Name Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + char product_name[13]; + +} S_PRODUCT_NAME_DATA; + +/** + * \brief Color point Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char white_point_index_1; + unsigned short white_x_1; + unsigned short white_y_1; + unsigned char gamma_1; + unsigned char white_point_index_2; + unsigned short white_x_2; + unsigned short white_y_2; + unsigned char gamma_2; +} S_COLOR_POINT_DATA; + +/** + * \brief Standard Timing Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned short standard_timings[6]; +} S_STANDARD_TIMING_DATA; + +/** + * \brief Color Management Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char version; + unsigned short red_a3; + unsigned short red_a2; + unsigned short green_a3; + unsigned short green_a2; + unsigned short blue_a3; + unsigned short blue_a2; +} S_COLOR_MANAGEMENT_DATA; + +/** + * \brief CVT 3 Byte Code Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char version; + unsigned short addressable_lines[4]; + unsigned char aspect_ratio[4]; + unsigned char preferred_vertical_rate[4]; + unsigned char supported_vertical_rate_and_blanking[4]; + +} S_CVT_TIMING_CODES_DATA; + +/** + * \brief Established Timings 3 Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char version; + unsigned char established_timings[6]; +} S_ESTABLISHED_TIMINGS_3_DATA; + +/** + * \brief Dummy Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; +} S_DUMMY_DATA; + +/** + * \brief Manufacturer Specific Descriptor structure + */ +typedef struct { + S_DESCRIPTOR_HEADER_DATA header; + unsigned char desc_data[18]; +} S_MANUFACTURER_SPECIFIC_DATA; + +/** + * \brief CEA-861 extension structure + */ +typedef struct { + unsigned char revision; + unsigned char underscan; + unsigned char audio; +} S_CEA861_DATA; + +/** + * \brief Extended Display Identification Data (EDID) structure + */ +typedef struct { + unsigned char header[8]; + char manufacturer_name[4]; + unsigned short product_code; + unsigned int serial_number; + unsigned char week; + unsigned short year; + unsigned short edid_version; + unsigned char video_input_definition; + unsigned char horizontal_size; + unsigned char vertical_size; + unsigned char gamma; + unsigned char feature_support; + unsigned short chromacity_coorditates_red_x; + unsigned short chromacity_coorditates_red_y; + unsigned short chromacity_coorditates_green_x; + unsigned short chromacity_coorditates_green_y; + unsigned short chromacity_coorditates_blue_x; + unsigned short chromacity_coorditates_blue_y; + unsigned short chromacity_coorditates_white_x; + unsigned short chromacity_coorditates_white_y; + unsigned char established_timing_1; + unsigned char established_timing_2; + unsigned char manufacturer_timing; + unsigned short standard_timings[8]; + unsigned char descriptors[4][MAX_DESCRIPTOR_LENGTH]; + unsigned char extensions; +} S_EDID_DATA; + +EDID_PARSER_RESULT edid_parse(S_EDID_DATA *edid, unsigned char *raw_data, + unsigned int len); + +#endif /* EDID_PARSER_H */ diff --git a/drivers/video/imx/hdp/externs.h b/drivers/video/imx/hdp/externs.h new file mode 100644 index 000000000000..fe4b13e4755c --- /dev/null +++ b/drivers/video/imx/hdp/externs.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 2017-2018 NXP + * + ****************************************************************************** + * + * externs.h + * + ****************************************************************************** + */ + +#ifndef EXTERNS_H_ +#define EXTERNS_H_ + +#ifndef __UBOOT__ +#include + +#else +#include +#endif +/** + * \addtogroup UTILS + * \{ + */ +/** + * \brief read from apb + * \param addr - address to read + * \param value - pointer to store value + * \return non-zero value if error + */ +/*extern int cdn_bus_read(unsigned int addr, unsigned int* value);*/ + +/** + * \brief write to apb + * \param addr - address to write + * \param value - value to write + * \return non-zero if error + */ +/*extern int cdn_bus_write(unsigned int addr, unsigned int value);*/ + +uint32_t cdn_apb_read(uint32_t addr, uint32_t *value); +uint32_t cdn_sapb_read(uint32_t addr, uint32_t *value); +uint32_t cdn_apb_write(uint32_t addr, uint32_t value); +uint32_t cdn_sapb_write(uint32_t addr, uint32_t value); +#endif diff --git a/drivers/video/imx/hdp/general_handler.h b/drivers/video/imx/hdp/general_handler.h new file mode 100644 index 000000000000..4a3132cf06e8 --- /dev/null +++ b/drivers/video/imx/hdp/general_handler.h @@ -0,0 +1,163 @@ +/****************************************************************************** + * + * 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 + * + ****************************************************************************** + * + * general_handler.h + * + ****************************************************************************** + */ + +#ifndef GENERAL_HANDLER_H +#define GENERAL_HANDLER_H + +/** + * \file + * \brief general handler, checks available messages, receives + * it from mailbox, handles requests and sends response + * to the host + */ +#define DP_TX_MAIL_HANDLER_REQUEST_BUFFER_LEN 256 + +/** + * \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) \ +do { \ + ptr = 0; \ + if ((bank == 0x22) || (bank == 0x20) || (bank == 0x0b) || \ + (bank == 0x09) || (bank == 0x0A)) \ + ptr = (unsigned int *)(bank << 8 | reg_no); \ +} while (0) + +#define select_reg(bank, reg_no, ptr) \ + ptr = (unsigned int *)(bank << 8 | reg_no) + +#define select_reg4(pmsb, p2, p3, plsb, ptr) \ + ptr = (unsigned int *)((pmsb << 24) | (p2 << 16) | \ + (p3 << 8) | (plsb << 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/video/imx/hdp/hdmi.h b/drivers/video/imx/hdp/hdmi.h new file mode 100644 index 000000000000..a8989829f260 --- /dev/null +++ b/drivers/video/imx/hdp/hdmi.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Copyright (C) 2015-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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 { + unsigned char sink_ver; + unsigned char manufacturer_oui_1; + unsigned char manufacturer_oui_2; + unsigned char manufacturer_oui_3; + unsigned char devId[8]; + unsigned char hardware_major_rev; + unsigned char hardware_minor_rev; + unsigned char software_major_rev; + unsigned char software_minor_rev; + unsigned char manufacturerSpecific[34]; +} S_HDMI_SCDC_SET_MSG; + +typedef struct { + unsigned char source_ver; + unsigned char TMDS_Config; + unsigned char config_0; + unsigned char 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 /*_HDMI__ */ diff --git a/drivers/video/imx/hdp/mhl_hdtx_top.h b/drivers/video/imx/hdp/mhl_hdtx_top.h new file mode 100644 index 000000000000..ee105f824891 --- /dev/null +++ b/drivers/video/imx/hdp/mhl_hdtx_top.h @@ -0,0 +1,220 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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/video/imx/hdp/opcodes.h b/drivers/video/imx/hdp/opcodes.h new file mode 100644 index 000000000000..fdc661c119bc --- /dev/null +++ b/drivers/video/imx/hdp/opcodes.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * 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 + * + ****************************************************************************** + * + * 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 256 +# 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_DBG_SET 0xF0 +# define DP_TX_OPCODE_READ_I2C_REQUEST 0xA5 +# define DP_TX_OPCODE_WRITE_I2C_REQUEST 0xA6 +# define DP_TX_OPCODE_MESSAGE_FILTER 0xA7 +# 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 DP_TX_OPCODE_MESSAGE 0x10 +# define DP_TX_OPCODE_READ_I2C_RESPONSE 0x50 +# define DP_TX_OPCODE_WRITE_I2C_RESPONSE 0x60 +# 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/video/imx/hdp/source_car.h b/drivers/video/imx/hdp/source_car.h new file mode 100644 index 000000000000..1a5f85f8aaad --- /dev/null +++ b/drivers/video/imx/hdp/source_car.h @@ -0,0 +1,179 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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_HDTX_PIXEL_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0) +#define F_HDTX_PIXEL_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0) +#define F_HDTX_PIXEL_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1) +#define F_HDTX_PIXEL_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1) +#define F_HDTX_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2) +#define F_HDTX_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2) +#define F_HDTX_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3) +#define F_HDTX_SYS_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 3)) >> 3) +#define F_HDTX_PHY_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4) +#define F_HDTX_PHY_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4) +#define F_HDTX_PHY_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5) +#define F_HDTX_PHY_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5) +#define F_HDTX_PHY_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 6) +#define F_HDTX_PHY_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6) +#define F_HDTX_PHY_CHAR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7) +#define F_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_CFG_DPTX_VIF_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 0) +#define F_CFG_DPTX_VIF_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 0)) >> 0) +#define F_CFG_DPTX_VIF_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 1) +#define F_CFG_DPTX_VIF_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 1)) >> 1) +#define F_DPTX_SYS_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 2) +#define F_DPTX_SYS_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 2)) >> 2) +#define F_DPTX_SYS_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 3) +#define F_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_DPTX_PHY_CHAR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 6) +#define F_DPTX_PHY_CHAR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6) +#define F_DPTX_PHY_CHAR_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7) +#define F_DPTX_PHY_CHAR_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 7)) >> 7) +#define F_DPTX_PHY_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 8) +#define F_DPTX_PHY_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 8)) >> 8) +#define F_DPTX_PHY_DATA_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 9) +#define F_DPTX_PHY_DATA_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 9)) >> 9) +#define F_DPTX_FRMR_DATA_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 10) +#define F_DPTX_FRMR_DATA_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 10)) >> 10) +#define F_DPTX_FRMR_DATA_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 11) +#define F_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_SPDIF_CDR_CLK_EN(x) (((x) & ((1 << 1) - 1)) << 4) +#define F_SPDIF_CDR_CLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 4)) >> 4) +#define F_SPDIF_CDR_CLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 5) +#define F_SPDIF_CDR_CLK_RSTN_EN_RD(x) (((x) & (((1 << 1) - 1) << 5)) >> 5) +#define F_SPDIF_MCLK_EN(x) (((x) & ((1 << 1) - 1)) << 6) +#define F_SPDIF_MCLK_EN_RD(x) (((x) & (((1 << 1) - 1) << 6)) >> 6) +#define F_SPDIF_MCLK_RSTN_EN(x) (((x) & ((1 << 1) - 1)) << 7) +#define F_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/video/imx/hdp/source_phy.h b/drivers/video/imx/hdp/source_phy.h new file mode 100644 index 000000000000..540809db9713 --- /dev/null +++ b/drivers/video/imx/hdp/source_phy.h @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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/video/imx/hdp/source_pif.h b/drivers/video/imx/hdp/source_pif.h new file mode 100644 index 000000000000..b9cbe16659d0 --- /dev/null +++ b/drivers/video/imx/hdp/source_pif.h @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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) & ((1 << 32) - 1)) << 0) */ +/*# define F_DATA_WR_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0) */ +#define F_DATA_WR(x) (((x) & 0xffffffff) << 0) +#define F_DATA_WR_RD(x) (((x) & 0xffffffff) >> 0) + +/* register SOURCE_PIF_DATA_RD */ +#define SOURCE_PIF_DATA_RD 5 +#define F_FIFO2_DATA_OUT(x) (((x) & ((1 << 32) - 1)) << 0) +#define F_FIFO2_DATA_OUT_RD(x) (((x) & (((1 << 32) - 1) << 0)) >> 0) + +/* 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/video/imx/hdp/source_vif.h b/drivers/video/imx/hdp/source_vif.h new file mode 100644 index 000000000000..a9b6c00154fb --- /dev/null +++ b/drivers/video/imx/hdp/source_vif.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * Copyright (C) 2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * 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/video/imx/hdp/test_base_sw.c b/drivers/video/imx/hdp/test_base_sw.c new file mode 100644 index 000000000000..fc2afa0fee68 --- /dev/null +++ b/drivers/video/imx/hdp/test_base_sw.c @@ -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-2018 NXP + * + ****************************************************************************** + * + * test_base_sw.c + * + ****************************************************************************** + */ + +#ifndef __UBOOT__ +#include +#include +#include +#else +#include +#include + +#ifdef CONFIG_ARCH_IMX8M +/* mscale */ +#define HDMI_BASE 0x32c00000 +#define HDMI_PHY_BASE 0x32c80000 +#define HDMI_SEC_BASE 0x32e40000 +#endif +#ifdef CONFIG_ARCH_MX8 +/* QM */ +#define HDMI_BASE 0x56268000 +#define HDMI_SEC_BASE 0x56269000 +#define HDMI_OFFSET_ADDR 0x56261008 +#define HDMI_SEC_OFFSET_ADDR 0x5626100c +#endif + +#endif + +#ifdef CONFIG_ARCH_IMX8M +int cdn_apb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = addr + HDMI_BASE; + temp = __raw_readl(tmp_addr); + *value = temp; + return 0; +} + +int cdn_apb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = addr + HDMI_BASE; + + __raw_writel(value, tmp_addr); + return 0; +} + +int cdn_sapb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = addr + HDMI_SEC_BASE; + temp = __raw_readl(tmp_addr); + *value = temp; + return 0; +} + +int cdn_sapb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = addr + HDMI_SEC_BASE; + __raw_writel(value, tmp_addr); + return 0; +} + +void cdn_sleep(uint32_t ms) +{ + mdelay(ms); +} + +void cdn_usleep(uint32_t us) +{ + udelay(us); +} +#endif +#ifdef CONFIG_ARCH_MX8 +int cdn_apb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = (addr & 0xfff) + HDMI_BASE; + + /* printf("%s():%d addr = 0x%08x, tmp_addr = 0x%08x, offset = 0x%08x\n", + __func__, __LINE__, addr, (unsigned int)tmp_addr, addr>>12); */ + + __raw_writel(addr >> 12, HDMI_OFFSET_ADDR); + + temp = __raw_readl(tmp_addr); + /* printf("%s():%d temp = 0x%08x\n", __func__, __LINE__, temp ); */ + + *value = temp; + return 0; +} + +int cdn_apb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = (addr & 0xfff) + HDMI_BASE; + + /*printf("%s():%d addr=0x%08x, taddr=0x%08x, off=0x%08x, val=0x%08x\n", + __func__, __LINE__, addr, (unsigned int)tmp_addr, + addr>>12, value);*/ + + __raw_writel(addr >> 12, HDMI_OFFSET_ADDR); + + /* printf("%s():%d\n", __func__, __LINE__); */ + __raw_writel(value, tmp_addr); + + return 0; +} + +int cdn_sapb_read(unsigned int addr, unsigned int *value) +{ + unsigned int temp; + uint64_t tmp_addr = (addr & 0xfff) + HDMI_SEC_BASE; + + __raw_writel(addr >> 12, HDMI_SEC_OFFSET_ADDR); + + temp = __raw_readl(tmp_addr); + *value = temp; + return 0; +} + +int cdn_sapb_write(unsigned int addr, unsigned int value) +{ + uint64_t tmp_addr = (addr & 0xfff) + HDMI_SEC_BASE; + + __raw_writel(addr >> 12, HDMI_SEC_OFFSET_ADDR); + __raw_writel(value, tmp_addr); + + return 0; +} + +void cdn_sleep(uint32_t ms) +{ + mdelay(ms); +} + +void cdn_usleep(uint32_t us) +{ + udelay(us); +} +#endif diff --git a/drivers/video/imx/hdp/util.c b/drivers/video/imx/hdp/util.c new file mode 100644 index 000000000000..e74aaa509cce --- /dev/null +++ b/drivers/video/imx/hdp/util.c @@ -0,0 +1,329 @@ +/****************************************************************************** + * + * 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 "externs.h" +#ifndef __UBOOT__ +#include +#endif +#include "apb_cfg.h" +#include "opcodes.h" +#ifndef __UBOOT__ +#include + +#endif +state_struct state; + +int cdn_bus_read(unsigned int addr, unsigned int *value) +{ + return state.bus_type ? + cdn_sapb_read(addr, value) : cdn_apb_read(addr, value); +} + +int cdn_bus_write(unsigned int addr, unsigned int value) +{ + return state.bus_type ? + cdn_sapb_write(addr, value) : cdn_apb_write(addr, value); +} + +void internal_itobe(int val, volatile unsigned char *dest, int bytes) +{ + int i; + for (i = bytes - 1; i >= 0; --i) { + dest[i] = (unsigned char)val; + val >>= 8; + } +} + +uint32_t internal_betoi(volatile uint8_t const *src, uint8_t bytes) +{ + uint32_t ret = 0; + int i; + + if (bytes > sizeof(ret)) { + printf("Warning. Read request for payload larger then supported.\n"); + bytes = sizeof(ret); + } + + for (i = 0; i < bytes; ++i) { + ret <<= 8; + ret |= (unsigned int)src[i]; + } + + return ret; +} + +unsigned int internal_mkmsg(volatile unsigned char *dest, int valno, ...) +{ + va_list vl; + unsigned int len = 0; + va_start(vl, valno); + len = internal_vmkmsg(dest, valno, vl); + va_end(vl); + return len; +} + +unsigned int internal_vmkmsg(volatile unsigned char *dest, int valno, + va_list vl) +{ + unsigned int 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(unsigned char module, unsigned char opcode, + int valno, ...) +{ + va_list vl; + va_start(vl, valno); + internal_vtx_mkfullmsg(module, opcode, valno, vl); + va_end(vl); +} + +void internal_vtx_mkfullmsg(unsigned char module, unsigned char opcode, + int valno, va_list vl) +{ + unsigned int len = + internal_vmkmsg(state.txbuffer + INTERNAL_CMD_HEAD_SIZE, valno, vl); + internal_mbox_tx_enable(module, opcode, len); + state.txenable = 1; + state.running = 1; +} + +void internal_readmsg(int valno, ...) +{ + va_list vl; + va_start(vl, valno); + internal_vreadmsg(valno, vl); + va_end(vl); +} + +void internal_vreadmsg(int valno, va_list vl) +{ + uint8_t *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) { + *((unsigned char **)ptr) = src; + } else if (size > 0) { + switch ((size_t) size) { + case sizeof(uint8_t): + *((uint8_t *)ptr) = internal_betoi(src, size); + break; + case sizeof(uint16_t): + *((uint16_t *)ptr) = internal_betoi(src, size); + break; + case 3: /* 3-byte value (e.g. DPCD address) + can be safely converted from BE.*/ + case sizeof(uint32_t): + *((uint32_t *)ptr) = internal_betoi(src, size); + break; + default: + printf("Warning. Unsupported variable size.\n"); + memcpy(ptr, src, size); + }; + + src += size; + } else { + memcpy(ptr, src, -size); + src -= size; + } + } +} + +INTERNAL_MBOX_STATUS mailbox_write(unsigned char val) +{ + INTERNAL_MBOX_STATUS ret; + unsigned int full; + if (cdn_bus_read(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(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(volatile unsigned char *val) +{ + INTERNAL_MBOX_STATUS ret; + unsigned int empty; + unsigned int rd; + if (cdn_bus_read(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(MAILBOX0_RD_DATA << 2, &rd)) { + ret.rx_status = CDN_RX_APB_ERROR; + return ret; + } + *val = (unsigned char)rd; + ret.rx_status = CDN_RX_READ; + return ret; +} + +INTERNAL_MBOX_STATUS internal_mbox_tx_process(void) +{ + unsigned int txcount = 0; + unsigned int length = + (unsigned int)state.txbuffer[2] << 8 | (unsigned int)state. + txbuffer[3]; + INTERNAL_MBOX_STATUS ret = {.txend = 0 }; + ret.tx_status = CDN_TX_NOTHING; + INTERNAL_MBOX_STATUS tx_ret; + if (!state.txenable) + return ret; + while ((tx_ret.tx_status = + mailbox_write(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(void) +{ + unsigned int rxcount = 0; + INTERNAL_MBOX_STATUS ret = { 0, 0, 0, 0 }; + INTERNAL_MBOX_STATUS rx_ret; + while ((rx_ret.rx_status = + mailbox_read(state.rxbuffer + state.rxi).rx_status) == + CDN_RX_READ) { + rxcount++; + if (++state.rxi >= 4 + + ((unsigned int)state.rxbuffer[2] << 8 | + (unsigned int)state.rxbuffer[3])) { /* end of message */ + state.rxi = 0; + ret.rxend = 1; + state.rxenable = 0; + break; + } + } + ret.rx_status = rxcount ? CDN_RX_READ : CDN_RX_EMPTY; + return ret; +} + +unsigned int internal_apb_available(void) +{ + return !(state.rxenable || state.txenable); +} + +void internal_mbox_tx_enable(unsigned char module, unsigned char opcode, + unsigned short length) +{ + state.txbuffer[0] = opcode; + state.txbuffer[1] = module; + state.txbuffer[2] = (unsigned char)(length >> 8); + state.txbuffer[3] = (unsigned char)length; + state.txenable = 1; +} + +CDN_API_STATUS internal_test_rx_head(unsigned char module, unsigned char 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(void) +{ + return internal_test_rx_head(state.txbuffer[1], state.txbuffer[0]); +} + +void print_fw_ver(void) +{ + unsigned short ver, verlib; + cdn_api_general_getcurversion(&ver, &verlib); + printf("FIRMWARE VERSION: %d, LIB VERSION: %d\n", ver, verlib); +} + +unsigned short internal_get_msg_len(void) +{ + return ((unsigned short)state.rxbuffer[2] << 8) | (unsigned short)state. + rxbuffer[3]; +} diff --git a/drivers/video/imx/hdp/util.h b/drivers/video/imx/hdp/util.h new file mode 100644 index 000000000000..6e8b6b7f6f7f --- /dev/null +++ b/drivers/video/imx/hdp/util.h @@ -0,0 +1,281 @@ +/****************************************************************************** + * + * 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 + * + ****************************************************************************** + * + * util.h + * + ****************************************************************************** + */ + +#ifndef UTIL_H_ +#define UTIL_H_ + +#include "API_General.h" +#ifndef __UBOOT__ +#include +#include +#else +#include +#endif +/** + * \addtogroup UTILS + * \{ + */ +#define INTERNAL_CMD_HEAD_SIZE 4 + +/** + * \brief expands to blocking function body + * \param x - function call + */ +#define internal_block_function(x) \ +do { \ + CDN_API_STATUS ret; \ + do { \ + ret = x; \ + } while (ret == CDN_BSY || ret == CDN_STARTED); \ + return ret; \ +} while (0) + +/** + * \brief write message and write response (if any), non-blocking way. Also sets state.running = 0 + */ +#define INTERNAL_PROCESS_MESSAGES \ +do { \ + if (state.txenable && !internal_mbox_tx_process().txend) \ + return CDN_BSY; \ + if (state.rxenable && !internal_mbox_rx_process().rxend) \ + return CDN_BSY; \ + state.running = 0; \ +} while (0) + +#define internal_opcode_ok_or_return(module, opcode) \ +do { \ + CDN_API_STATUS ret = internal_test_rx_head(module, opcode); \ + if (ret != CDN_OK) \ + return ret; \ +} while (0) + +#define internal_opcode_match_or_return() \ +do { \ + CDN_API_STATUS ret = internal_test_rx_head_match(); \ + 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(module, opcode, bustype, command...) \ +do { \ + if (!state.running) { \ + internal_tx_mkfullmsg(module, opcode, command); \ + state.bus_type = bustype; \ + return CDN_STARTED; \ + } \ + INTERNAL_PROCESS_MESSAGES; \ +} while (0) + +/* macro for command with response with matching opcode, command format as in + mkfullmsg (with count) */ +#define internal_macro_command_txrx(module, opcode, bustype, command...) \ +do { \ + if (!state.running) { \ + internal_tx_mkfullmsg(module, opcode, command); \ + state.bus_type = bustype; \ + state.rxenable = 1; \ + return CDN_STARTED; \ + } \ + INTERNAL_PROCESS_MESSAGES; \ + internal_opcode_match_or_return(); \ +} while (0) + +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 */ + unsigned char rxend:1; + /** end of tx message reached */ + unsigned char txend:1; +} INTERNAL_MBOX_STATUS; + +/** + * \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 unsigned char *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 + */ +uint32_t internal_betoi(volatile uint8_t const *src, uint8_t bytes); + +/** + * \brief create message from size and value pairs; also sets + * state.running 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: + * + * unsigned short x = 0xAABB; + * + * internal_mkmsg(dest, 3, 1, 1, 2, 3, -2, &x); + * + * will write 01 00 03 AA BB to dest + */ +unsigned int internal_mkmsg(volatile unsigned char *dest, int valno, ...); +unsigned int internal_vmkmsg(volatile unsigned char *dest, int valno, + va_list vl); + +/** + * \brief setup message header in txBuffer, set txEnable = 1 + */ +void internal_mbox_tx_enable(unsigned char module, unsigned char opcode, + unsigned short 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(unsigned char module, unsigned char opcode, + int valno, ...); +void internal_vtx_mkfullmsg(unsigned char module, unsigned char 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(int valno, ...); +void internal_vreadmsg(int valno, va_list vl); + +INTERNAL_MBOX_STATUS internal_mbox_tx_process(void); +/** + * \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(void); + +/** + * \brief check if apb is available + * \return !(rxEnable && txEable) + */ +unsigned int internal_apb_available(void); + +/** + * \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(unsigned char module, + unsigned char opcode); + +CDN_API_STATUS internal_test_rx_head_match(void); + +/** + * \brief print current fw and lib version + */ +void print_fw_ver(void); + +typedef struct { + unsigned char txbuffer[1024]; + unsigned char rxbuffer[1024]; + unsigned int txi; /* iterators */ + unsigned int rxi; + unsigned char txenable; /*data readt to send*/ + unsigned char rxenable; + unsigned char running; + CDN_BUS_TYPE bus_type; + unsigned int tmp; +} state_struct; + +extern state_struct state; +extern int cdn_bus_read(unsigned int addr, unsigned int* value); +extern int cdn_bus_write(unsigned int addr, unsigned int value); +unsigned short internal_get_msg_len(void); + +#endif diff --git a/drivers/video/imx/hdp/vic_table.c b/drivers/video/imx/hdp/vic_table.c new file mode 100644 index 000000000000..c49840081899 --- /dev/null +++ b/drivers/video/imx/hdp/vic_table.c @@ -0,0 +1,68 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * This file was auto-generated. Do not edit it manually. + * + ****************************************************************************** + * + * vic_table.c + * + ****************************************************************************** + */ +#include "vic_table.h" + +const unsigned int vic_table[VIC_MODE_COUNT][27] = { + {858, 720, 138, 62, 16, 60, 525, 480, 45, 6, 9, 30, 59, 27000, + PROGRESSIVE, ACTIVE_LOW, ACTIVE_LOW, 1, 65535, 1, 46, 65535, 65535, 3, + 8, 0}, + {1650, 1280, 370, 40, 110, 220, 750, 720, 30, 5, 5, 20, 60, 74250, + PROGRESSIVE, ACTIVE_HIGH, ACTIVE_HIGH, 1, 65535, 1, 31, 65535, 65535, + 4, 8, 0}, + {2200, 1920, 280, 44, 88, 148, 1125, 1080, 45, 5, 4, + 36, 60, 148500, PROGRESSIVE, ACTIVE_HIGH, + ACTIVE_HIGH, 1, 65535, 1, 46, 65535, 65535, 16, 8, 0}, + {4400, 3840, 560, 88, 176, 296, 2250, 2160, 90, 10, 8, 72, 60, + 594000, PROGRESSIVE, ACTIVE_HIGH, ACTIVE_HIGH, 4, 266, 262, 22, 525, + 285, 97, 8, 0}, + {4400, 3840, 560, 88, 176, 296, 2250, 2160, 90, 10, 8, 72, 30, + 297000, PROGRESSIVE, ACTIVE_HIGH, ACTIVE_HIGH, 4, 266, 262, 22, 525, + 285, 95, 8, 0}, +}; diff --git a/drivers/video/imx/hdp/vic_table.h b/drivers/video/imx/hdp/vic_table.h new file mode 100644 index 000000000000..dce88347b7e4 --- /dev/null +++ b/drivers/video/imx/hdp/vic_table.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Copyright 2017-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. + * + ****************************************************************************** + * + * This file was auto-generated. Do not edit it manually. + * + ****************************************************************************** + * + * vic_table.h + * + ****************************************************************************** + */ + +#ifndef VIC_TABLE_H_ +#define VIC_TABLE_H_ + +#define PROGRESSIVE 0 +#define INTERLACED 1 + +#define ACTIVE_LOW 0 +#define ACTIVE_HIGH 1 + +typedef enum { + H_TOTAL, + H_ACTIVE, + H_BLANK, + HSYNC, + FRONT_PORCH, + BACK_PORCH, + /* H_FREQ_KHZ, */ + V_TOTAL, + V_ACTIVE, + V_BLANK, + VSYNC, + TYPE_EOF, + SOF, + V_FREQ_HZ, + PIXEL_FREQ_KHZ, + I_P, + HSYNC_POL, + VSYNC_POL, + START_OF_F0, + START_OF_F1, + VSYNC_START_INTERLACED_F0, + VSYNC_END_INTERLACED_F0, + VSYNC_START_INTERLACED_F1, + VSYNC_END_INTERLACED_F1, + VIC, + VIC_R3_0, + VIC_PR, +} MSA_PARAM; + +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_7 = 270, + 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 enum { + VIC_MODE_3_59_94Hz, + VIC_MODE_4_60Hz, + VIC_MODE_16_60Hz, + VIC_MODE_97_60Hz, + VIC_MODE_95_30Hz, + VIC_MODE_COUNT +} VIC_MODES; + +extern const unsigned int vic_table[VIC_MODE_COUNT][27]; + +#endif diff --git a/drivers/video/imx/hdp_load.c b/drivers/video/imx/hdp_load.c new file mode 100644 index 000000000000..66eb3e93856f --- /dev/null +++ b/drivers/video/imx/hdp_load.c @@ -0,0 +1,107 @@ +/* + * Copyright 2017-2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include "API_General.h" +#include "scfw_utils.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define ON 1 +#define OFF 0 + +static void display_set_power(int onoff) +{ + sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; + + SC_PM_SET_RESOURCE_POWER_MODE(ipcHndl, SC_R_DC_0, onoff); + SC_PM_SET_RESOURCE_POWER_MODE(ipcHndl, SC_R_HDMI, onoff); +} + +static void display_set_clocks(void) +{ + sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; + const sc_pm_clock_rate_t pll = 1188000000; + const sc_pm_clock_rate_t hdmi_core_clock = pll / 10; + const sc_pm_clock_rate_t hdmi_bus_clock = pll / 14; + + SC_PM_SET_RESOURCE_POWER_MODE(ipcHndl, + SC_R_HDMI_PLL_0, SC_PM_PW_MODE_OFF); + SC_PM_SET_CLOCK_RATE(ipcHndl, + SC_R_HDMI_PLL_0, SC_PM_CLK_PLL, pll); + SC_PM_SET_RESOURCE_POWER_MODE(ipcHndl, + SC_R_HDMI_PLL_0, SC_PM_PW_MODE_ON); + + /* HDMI DI Bus Clock */ + SC_PM_SET_CLOCK_RATE(ipcHndl, + SC_R_HDMI, SC_PM_CLK_MISC4, hdmi_bus_clock); + /* HDMI DI Core Clock */ + SC_PM_SET_CLOCK_RATE(ipcHndl, + SC_R_HDMI, SC_PM_CLK_MISC2, hdmi_core_clock); +} + +static void display_enable_clocks(int enable) +{ + sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; + + SC_PM_CLOCK_ENABLE(ipcHndl, SC_R_HDMI_PLL_0, SC_PM_CLK_PLL, enable); + SC_PM_CLOCK_ENABLE(ipcHndl, SC_R_HDMI, SC_PM_CLK_MISC2, enable); + SC_PM_CLOCK_ENABLE(ipcHndl, SC_R_HDMI, SC_PM_CLK_MISC4, enable); +} + +int do_hdp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (argc < 2) + return 0; + + if (strncmp(argv[1], "tracescfw", 9) == 0) { + g_debug_scfw = 1; + printf("Enabled SCFW API tracing\n"); + } else if (strncmp(argv[1], "load", 4) == 0) { + unsigned long address = 0; + unsigned long offset = 0x2000; + const int iram_size = 0x10000; + const int dram_size = 0x8000; + + if (argc > 2) { + address = simple_strtoul(argv[2], NULL, 0); + if (argc > 3) + offset = simple_strtoul(argv[3], NULL, 0); + } else + printf("Missing address\n"); + + printf("Loading hdp firmware from 0x%016lx offset 0x%016lx\n", + address, offset); + display_set_power(SC_PM_PW_MODE_ON); + display_set_clocks(); + display_enable_clocks(ON); + cdn_api_loadfirmware((unsigned char *)(address + offset), + iram_size, + (unsigned char *)(address + offset + + iram_size), + dram_size); + display_enable_clocks(OFF); + printf("Loading hdp firmware Complete\n"); + /* do not turn off hdmi power or firmware load will be lost */ + } else { + printf("test error argc %d\n", argc); + } + + return 0; +} +/***************************************************/ + +U_BOOT_CMD( + hdp, CONFIG_SYS_MAXARGS, 1, do_hdp, + "load hdmi firmware ", + "[] ...\n" + "hdpload [address] []\n" + " address - address where the binary image starts\n" + " - IRAM offset in the binary image (8192 default)\n" + "tracescfw - Trace SCFW API calls for video commands\n" + ); diff --git a/drivers/video/imx/imx8_hdmi.c b/drivers/video/imx/imx8_hdmi.c new file mode 100644 index 000000000000..08dc914759b6 --- /dev/null +++ b/drivers/video/imx/imx8_hdmi.c @@ -0,0 +1,296 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#include "API_General.h" +#include "vic_table.h" +#include "API_HDMITX.h" +#include "apb_cfg.h" +#include "externs.h" +#include "API_AVI.h" +#include "address.h" +#include "source_car.h" +#include "source_phy.h" +#include "API_AFE.h" +#include "source_vif.h" +#include "general_handler.h" +#include "mhl_hdtx_top.h" + + +#ifdef CONFIG_MX8QM +#include "API_AFE_mcu1_dp.h" +#include "API_AFE_ss28fdsoi_kiran_hdmitx.h" +#endif + +#ifdef CONFIG_IMX8M +#include "API_AFE_t28hpc_hdmitx.h" +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define ON 1 +#define OFF 0 + +unsigned long g_encoding = 1; /* 1 RGB, 2 YUV 444, 4 YUV 422, 8 YUV 420 */ +unsigned long g_color_depth = 8; /* 8 pits per color */ + +static int imx8_hdmi_set_vic_mode(int vic, + struct video_mode_settings *vms) +{ + /*struct video_mode_settings *vms = &vm_settings[VM_USER]; */ + uint32_t pixel_clock_kHz; + uint32_t frame_rate_Hz; + uint32_t frame_rate_frac_Hz; + uint32_t cea_vic; + char iflag; + + if (vic >= VIC_MODE_COUNT) { + debug("%s(): unsupported VIC\n", __func__); + return -1; + } + + + vms->hfp = vic_table[vic][FRONT_PORCH]; + vms->hbp = vic_table[vic][BACK_PORCH]; + vms->hsync = vic_table[vic][HSYNC]; + vms->vfp = vic_table[vic][TYPE_EOF]; + vms->vbp = vic_table[vic][SOF]; + vms->vsync = vic_table[vic][VSYNC]; + vms->xres = vic_table[vic][H_ACTIVE]; + vms->yres = vic_table[vic][V_ACTIVE]; + + vms->hpol = vic_table[vic][HSYNC_POL] != 0; + vms->vpol = vic_table[vic][VSYNC_POL] != 0; + + cea_vic = vic_table[vic][VIC]; + if (vic_table[vic][I_P] != 0) + iflag = 'i'; + else + iflag = 'p'; + pixel_clock_kHz = vic_table[vic][PIXEL_FREQ_KHZ]; + frame_rate_Hz = vic_table[vic][V_FREQ_HZ] * 1000; + frame_rate_frac_Hz = frame_rate_Hz % 1000; + frame_rate_Hz /= 1000; + + vms->pixelclock = pixel_clock_kHz; + + debug("Cadence VIC %3d, CEA VIC %3d: %4d x %4d %c @ %3d.%03d [%6d kHz] Vpol=%d Hpol=%d\n", + vic, cea_vic, vms->xres, vms->yres, iflag, frame_rate_Hz, + frame_rate_frac_Hz, pixel_clock_kHz, vms->vpol, vms->hpol); + + debug(" mode timing fp sync bp h:%3d %3d %3d v:%3d %3d %3d\n", + vms->hfp, vms->hsync, vms->hbp, vms->vfp, vms->vsync, vms->vbp); + + return 0; + /*debug("leaving %s() ...\n", __func__); */ +} + +static int imx8_hdmi_init(int vic, + int encoding, + int color_depth, + bool pixel_clk_from_phy) +{ + int ret; +#ifdef CONFIG_MX8QM + sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; + void __iomem *hdmi_csr_base = (void __iomem *)0x56261000; +#endif + /*GENERAL_Read_Register_response regresp; */ + /*uint8_t sts; */ + uint32_t character_freq_khz; + + uint8_t echo_msg[] = "echo test"; + uint8_t echo_resp[sizeof(echo_msg) + 1]; + /*uint8_t response; */ + /*uint8_t dpcd_resp; */ + /*uint8_t hdcp_resp; */ + /*uint8_t capb_resp; */ + /*uint32_t temp; */ + + /*================================================================== */ + /* Parameterization: */ + /*================================================================== */ + + /* VIC Mode - index from vic_table (see API_SRC/vic_table.c) */ + VIC_MODES vic_mode = vic; + + /* Pixel Encodeing Format */ + /* 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 format = encoding; + /*VIC_PXL_ENCODING_FORMAT format = 1; */ + + /* B/W Balance Type: 0 no data, 1 IT601, 2 ITU709 */ + BT_TYPE bw_type = 0; + + /* bpp (bits per subpixel) - 8 24bpp, 10 30bpp, 12 36bpp, 16 48bpp */ + uint8_t bps = color_depth; + + /* Set HDMI TX Mode */ + /* Mode = 0 - DVI, 1 - HDMI1.4, 2 HDMI 2.0 */ + HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE ptype = 1; + + if (vic_mode == VIC_MODE_97_60Hz) + ptype = 2; + + /*================================================================== */ + /* Parameterization done */ + /*================================================================== */ +#ifdef CONFIG_MX8QM + /* set the pixel link mode and pixel type */ + SC_MISC_SET_CONTROL(ipcHndl, SC_R_HDMI, SC_C_PHY_RESET, 0); +#if 1 + SC_MISC_SET_CONTROL(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_ADDR, 1); + /*SC_MISC_SET_CONTROL(ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_ADDR, 0);*/ + if (g_clock_mode == CLOCK_MODES_HDMI_DUAL) { + SC_MISC_SET_CONTROL(ipcHndl, SC_R_DC_0, + SC_C_PXL_LINK_MST2_ADDR, 2); + /*SC_MISC_SET_CONTROL(ipcHndl, SC_R_DC_0, + SC_C_PXL_LINK_MST2_ADDR, 0); */ + __raw_writel(0x6, hdmi_csr_base); + } else +#endif + __raw_writel(0x34, hdmi_csr_base); +#endif + cdn_api_init(); + debug("CDN_API_Init completed\n"); + + ret = cdn_api_checkalive(); + debug("CDN_API_CheckAlive returned ret = %d\n", ret); + + if (ret) + return -EPERM; + + ret = cdn_api_general_test_echo_ext_blocking(echo_msg, + echo_resp, + sizeof(echo_msg), + CDN_BUS_TYPE_APB); + debug("_General_Test_Echo_Ext_blocking - (ret = %d echo_resp = %s)\n", + ret, echo_resp); + + /* Configure PHY */ + character_freq_khz = phy_cfg_t28hpc(4, vic_mode, bps, + format, pixel_clk_from_phy); + debug("phy_cfg_t28hpc (character_freq_mhz = %d)\n", + character_freq_khz); + + /*phy_reset(1); */ + +#ifdef CONFIG_MX8QM + SC_MISC_SET_CONTROL(ipcHndl, SC_R_HDMI, SC_C_PHY_RESET, 1); +#endif + hdmi_tx_t28hpc_power_config_seq(4); +#ifdef CONFIG_MX8QM + /* Set the lane swapping */ + ret = cdn_api_general_write_register_blocking + (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)); +#else + /* Set the lane swapping */ + ret = cdn_api_general_write_register_blocking + (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)); +#endif + debug("_General_Write_Register_blocking LANES_CONFIG ret = %d\n", ret); + + ret = CDN_API_HDMITX_Init_blocking(); + debug("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret); + + ret = CDN_API_HDMITX_Init_blocking(); + debug("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret); + + ret = CDN_API_HDMITX_Set_Mode_blocking(ptype, character_freq_khz); + debug("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret); + + ret = cdn_api_set_avi(vic_mode, format, bw_type); + debug("cdn_api_set_avi ret = %d\n", ret); + + ret = CDN_API_HDMITX_SetVic_blocking(vic_mode, bps, format); + debug("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); + +#ifdef CONFIG_MX8QM + { + GENERAL_Read_Register_response regresp; + /* adjust the vsync/hsync polarity */ + cdn_api_general_read_register_blocking(ADDR_SOURCE_VIF + + (HSYNC2VSYNC_POL_CTRL + << 2), + ®resp); + debug("Initial HSYNC2VSYNC_POL_CTRL: 0x%x\n", regresp.val); + if ((regresp.val & 0x3) != 0) + __raw_writel(0x4, hdmi_csr_base); + } +#endif + /*regresp.val &= ~0x03; // clear HSP and VSP bits */ + /*debug("Final HSYNC2VSYNC_POL_CTRL: 0x%x\n",regresp.val); */ + /*CDN_API_General_Write_Register_blocking(ADDR_DPTX_FRAMER + + (DP_FRAMER_SP << 2), + regresp.val); */ + + udelay(20000); + + return 0; +} + +int imx8_hdmi_enable(int encoding, + struct video_mode_settings *vms) +{ + int vic = 0; + const int use_phy_pixel_clk = 1; + + /* map the resolution to a VIC index in the vic table*/ + if ((vms->xres == 1280) && (vms->yres == 720)) + vic = 1; /* 720p60 */ + else if ((vms->xres == 1920) && (vms->yres == 1080)) + vic = 2; /* 1080p60 */ + else if ((vms->xres == 3840) && (vms->yres == 2160)) + vic = 3; /* 2160p60 */ + else /* if ((vms->xres == 720) && (vms->yres == 480)) */ + vic = 0; /* 480p60 */ + + imx8_hdmi_set_vic_mode(vic, vms); + return imx8_hdmi_init(vic, encoding, g_color_depth, use_phy_pixel_clk); +} + +void imx8_hdmi_disable(void) +{ + int ret; + GENERAL_READ_REGISTER_RESPONSE resp; + + resp.val = 0; + ret = cdn_api_general_read_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + &resp); + if (ret != CDN_OK) { + printf("%s(): dn_api_general_read_register_blocking failed\n", + __func__); + /*return;*/ + } + + resp.val &= ~F_DATA_EN(1); /* disable HDMI */ + /*resp.val |= F_SET_AVMUTE( 1);*/ + + ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD + + (HDTX_CONTROLLER << 2), + resp.val); + if (ret != CDN_OK) { + printf("%s(): dn_api_general_write_register_blocking failed\n", + __func__); + return; + } +} diff --git a/drivers/video/imx/scfw_utils.h b/drivers/video/imx/scfw_utils.h new file mode 100644 index 000000000000..6f6143db450a --- /dev/null +++ b/drivers/video/imx/scfw_utils.h @@ -0,0 +1,90 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _SCFW_UTILS_H_ +#define _SCFW_UTILS_H_ + +#include +#include + +static int g_debug_scfw; /* set to one to turn on SCFW API tracing */ + +#define SC_PM_SET_CLOCK_PARENT(__ipcHndl__, __res__, __clk__, __parent__) \ +do { \ + char _res_str[] = #__res__;\ + char _clk_str[] = #__clk__;\ + sc_err_t _ret;\ + if (g_debug_scfw) \ + printf("(%4d) sc_pm_set_clock_parent %s:%s -> %d\n",\ + __LINE__, _res_str, _clk_str, __parent__);\ + _ret = sc_pm_set_clock_parent(__ipcHndl__,\ + __res__, __clk__, __parent__);\ + if (_ret != SC_ERR_NONE) \ + printf("(%d)>> sc_pm_set_clock_parent failed! %s:%s -> %d (error = %d)\n",\ + __LINE__, _res_str, _clk_str, __parent__, _ret);\ +} while (0) + +#define SC_PM_SET_CLOCK_RATE(__ipcHndl__, __res__, __clk__, __rate__) \ +do { \ + char _res_str[] = #__res__;\ + char _clk_str[] = #__clk__;\ + sc_err_t _ret;\ + sc_pm_clock_rate_t _actual = __rate__;\ + if (g_debug_scfw) \ + printf("(%4d) sc_pm_set_clock_rate %s:%s -> %d\n",\ + __LINE__, _res_str, _clk_str, __rate__);\ + _ret = sc_pm_set_clock_rate(__ipcHndl__, __res__, __clk__, &_actual);\ + if (_ret != SC_ERR_NONE)\ + printf("(%4d)>> sc_pm_set_clock_rate failed! %s:%s -> %d (error = %d)\n",\ + __LINE__, _res_str, _clk_str, __rate__, _ret);\ + if (_actual != __rate__)\ + printf("(%4d)>> Actual rate for %s:%s is %d instead of %d\n", \ + __LINE__, _res_str, _clk_str, _actual, __rate__); \ +} while (0) + +#define SC_PM_CLOCK_ENABLE(__ipcHndl__, __res__, __clk__, __enable__) \ +do { \ + char _res_str[] = #__res__;\ + char _clk_str[] = #__clk__;\ + sc_err_t _ret;\ + if (g_debug_scfw) \ + printf("(%4d) sc_pm_clock_enable %s:%s -> %d\n",\ + __LINE__, _res_str, _clk_str, __enable__);\ + _ret = sc_pm_clock_enable(ipcHndl,\ + __res__, __clk__, __enable__, false);\ + if (_ret != SC_ERR_NONE)\ + printf("(%4d)>> sc_pm_clock_enable failed! %s:%s -> %d (error = %d)\n",\ + __LINE__, _res_str, _clk_str, __enable__, _ret);\ +} while (0) \ + +#define SC_MISC_SET_CONTROL(__ipcHndl__, __res__, __clk__, __value__) \ +do { \ + char _res_str[] = #__res__; \ + char _clk_str[] = #__clk__; \ + sc_err_t _ret; \ + if (g_debug_scfw) \ + printf("(%4d) sc_misc_set_control %s:%s -> %d\n",\ + __LINE__, _res_str, _clk_str, __value__);\ + _ret = sc_misc_set_control(ipcHndl, \ + __res__, __clk__, __value__); \ + if (_ret != SC_ERR_NONE) \ + printf("(%4d)>> sc_misc_set_control failed! %s:%s -> %d (error = %d)\n", \ + __LINE__, _res_str, _clk_str, __value__, _ret); \ +} while (0) + +#define SC_PM_SET_RESOURCE_POWER_MODE(__ipcHndl__, __res__, __enable__) \ +do { \ + char _res_str[] = #__res__; \ + sc_err_t _ret; \ + if (g_debug_scfw) \ + printf("(%4d) sc_pm_set_resource_power_mode %s -> %d\n",\ + __LINE__, _res_str, __enable__);\ + _ret = sc_pm_set_resource_power_mode(ipcHndl, __res__, __enable__);\ + if (_ret != SC_ERR_NONE) \ + printf("(%4d)>> sc_pm_set_resource_power_mode failed! %s -> %d (error = %d)\n", \ + __LINE__, _res_str, __enable__, _ret);\ +} while (0) + +#endif /*_SCFW_UTILS_H_ */ diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 373fee78a999..505c18dd6c60 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -337,6 +337,12 @@ BOOTENV_DEV_NAME_##devtypeu(devtypeu, devtypel, instance) #define BOOTENV_BOOT_TARGETS \ "boot_targets=" BOOT_TARGET_DEVICES(BOOTENV_DEV_NAME) "\0" +#ifndef BOOTENV_EXTRA_BOOT_PREFIXES +#define BOOTENV_EXTRA_BOOT_PREFIXES "" +#endif +#ifndef BOOTENV_EXTRA_BOOT_SCRIPTS +#define BOOTENV_EXTRA_BOOT_SCRIPTS "" +#endif #define BOOTENV_DEV(devtypeu, devtypel, instance) \ BOOTENV_DEV_##devtypeu(devtypeu, devtypel, instance) @@ -350,9 +356,9 @@ BOOTENV_SHARED_IDE \ BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_EFI \ - "boot_prefixes=/ /boot/\0" \ - "boot_scripts=boot.scr.uimg boot.scr\0" \ - "boot_script_dhcp=boot.scr.uimg\0" \ + "boot_prefixes=/boot/ /" BOOTENV_EXTRA_BOOT_PREFIXES "\0" \ + "boot_scripts=boot.scr.uimg boot.scr" BOOTENV_EXTRA_BOOT_SCRIPTS "\0" \ + "boot_script_dhcp=boot.scr.uimg" BOOTENV_EXTRA_BOOT_SCRIPTS "\0" \ BOOTENV_BOOT_TARGETS \ \ "boot_extlinux=" \ @@ -369,6 +375,9 @@ "fi\0" \ \ "boot_a_script=" \ + "setenv disk ${devnum}; " \ + "setenv dtype ${devtype}; " \ + "setenv bootpart ${distro_bootpart}; " \ "load ${devtype} ${devnum}:${distro_bootpart} " \ "${scriptaddr} ${prefix}${script}; " \ "source ${scriptaddr}\0" \ diff --git a/include/configs/imx8mq_hb.h b/include/configs/imx8mq_hb.h new file mode 100644 index 000000000000..932d159b93e3 --- /dev/null +++ b/include/configs/imx8mq_hb.h @@ -0,0 +1,270 @@ +/* + * Copyright 2018 SolidRun Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __IMX8M_HB_H +#define __IMX8M_HB_H + +#include +#include + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_CSF_SIZE 0x2000 /* 8K region */ +#endif + +#define CONFIG_SPL_TEXT_BASE 0x7E1000 +#define CONFIG_SPL_MAX_SIZE (124 * 1024) +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 + +#ifdef CONFIG_SPL_BUILD +/*#define CONFIG_ENABLE_DDR_TRAINING_DEBUG*/ +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" +#define CONFIG_SPL_STACK 0x187FF0 +#define CONFIG_SPL_BSS_START_ADDR 0x00180000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */ +#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x8000 /* 8 KB */ +#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000 +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */ +#define CONFIG_MALLOC_F_ADDR 0x182000 +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE /* For RAW image gives a error info not panic */ + +#undef CONFIG_DM_MMC +#undef CONFIG_DM_PMIC +#undef CONFIG_DM_PMIC_PFUZE100 + +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ + +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_PFUZE100 +#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 +#endif + +#define CONFIG_PREBOOT + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + +#define CONFIG_REMAKE_ELF + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* Flat Device Tree Definitions */ +#ifndef CONFIG_OF_BOARD_SETUP +#define CONFIG_OF_BOARD_SETUP +#endif + +#undef CONFIG_CMD_EXPORTENV +#undef CONFIG_CMD_IMPORTENV +#undef CONFIG_CMD_IMLS + +/* #define CONFIG_CMD_BMODE */ +#undef CONFIG_CMD_CRC32 +#undef CONFIG_BOOTM_NETBSD + +/* ENET Config */ +/* ENET1 */ +#if defined(CONFIG_CMD_NET) +#define CONFIG_MII +#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_FEC_MXC +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 4 +#define FEC_QUIRK_ENET_MAC +#define GP_RGMII_PHY_RESET IMX_GPIO_NR(1, 9) + +#define CONFIG_PHY_GIGE +#define IMX_FEC_BASE 0x30BE0000 + +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS +#endif + +/* Link Definitions */ +#define CONFIG_LOADADDR 0x40480000 +#define CONFIG_SYS_TEXT_BASE 0x40200000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x80000 +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_OFFSET (SZ_1M - CONFIG_ENV_SIZE) +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC1 */ + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (2*1024) + (16*1024)) * 1024) + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0xC0000000 /* 3GB DDR */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR + +/* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 2048 +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_IMX_BOOTAUX + +#define CONFIG_FSL_USDHC + +#define CONFIG_SYS_FSL_USDHC_NUM 2 +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 + +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ +#define CONFIG_SUPPORT_EMMC_RPMB +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +#define CONFIG_MXC_GPIO + +#define CONFIG_MXC_OCOTP +#define CONFIG_CMD_FUSE + +/* I2C Configs */ +#define CONFIG_SYS_I2C_SPEED 100000 + +/* USB configs */ +#ifndef CONFIG_SPL_BUILD +#define CONFIG_HAS_FSL_XHCI_USB + +#ifdef CONFIG_HAS_FSL_XHCI_USB +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 +#endif + +#define CONFIG_USB_DWC3 +#define CONFIG_USB_DWC3_GADGET +#define CONFIG_USBD_HS + +#define CONFIG_USB_GADGET_MASS_STORAGE +#define CONFIG_USB_GADGET_VBUS_DRAW 2 +#define CONFIG_USB_GADGET_DUALSPEED + +#endif + +#define CONFIG_OF_SYSTEM_SETUP + +/* Framebuffer */ +#ifdef CONFIG_VIDEO +#define CONFIG_VIDEO_BMP_RLE8 +#define CONFIG_SPLASH_SCREEN +#define CONFIG_SPLASH_SCREEN_ALIGN +#define CONFIG_BMP_16BPP +#define CONFIG_VIDEO_LOGO +#define CONFIG_VIDEO_BMP_LOGO +#endif + +#ifdef CONFIG_CMD_MMC +#if (CONFIG_SYS_FSL_USDHC_NUM == 1) +#define DISTRO_BOOT_DEV_MMC(func) func(MMC, mmc, 0) +#elif (CONFIG_SYS_FSL_USDHC_NUM == 2) +#define DISTRO_BOOT_DEV_MMC(func) func(MMC, mmc, 0) func(MMC, mmc, 1) +#else +#define DISTRO_BOOT_DEV_MMC(func) func(MMC, mmc, 0) func(MMC, mmc, 1) func(MMC, mmc, 2) +#endif +#else +#define DISTRO_BOOT_DEV_MMC(func) +#endif + +#ifdef CONFIG_USB_STORAGE +#define DISTRO_BOOT_DEV_USB(func) func(USB, usb, 0) +#else +#define DISTRO_BOOT_DEV_USB(func) +#endif + +#ifndef BOOT_TARGET_DEVICES +#define BOOT_TARGET_DEVICES(func) \ + DISTRO_BOOT_DEV_MMC(func) \ + DISTRO_BOOT_DEV_USB(func) +#endif + +#include + +#define BD_RAM_BASE 0x80000000 +#define BD_RAM_SCRIPT "40008000" +#define BD_RAM_KERNEL "40800000" +#define BD_RAM_RAMDISK "42800000" +#define BD_RAM_FDT "43000000" + +/* M4 specific */ +#define SYS_AUXCORE_BOOTDATA_DDR 0x80000000 +#define SYS_AUXCORE_BOOTDATA_TCM 0x007E0000 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200\0" \ + "env_dev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ + "env_part=" __stringify(CONFIG_SYS_MMC_ENV_PART) "\0" \ + "fdt_addr_r=0x43000000\0" \ + "fdt_file=fsl-imx8mq-hummingboard-pulse.dtb\0" \ + "fdtfile=fsl-imx8mq-hummingboard-pulse.dtb\0" \ + "ramdisk_addr_r=0x43800000\0" \ + "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ + "pxefile_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ + "scriptaddr=" __stringify(CONFIG_LOADADDR) "\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "m4boot=load ${devtype} ${devnum}:1 ${m4loadaddr} ${m4image}; " \ + "dcache flush; bootaux ${m4loadaddr}\0" \ + "m4image=m4_fw.bin\0" \ + "m4loadaddr="__stringify(SYS_AUXCORE_BOOTDATA_TCM)"\0" \ + "netargs=setenv bootargs console=${console},115200 root=/dev/nfs rw " \ + "ip=dhcp nfsroot=${tftpserverip}:${nfsroot},v3,tcp\0" \ + "netboot=run netargs; " \ + "if test -z \"${fdt_file}\" -a -n \"${soc}\"; then " \ + "setenv fdt_file ${soc}-${board}${boardver}.dtb; " \ + "fi; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${loadaddr} ${tftpserverip}:Image; " \ + "if ${get_cmd} ${fdt_addr_r} ${tftpserverip}:${fdt_file}; then " \ + "booti ${loadaddr} - ${fdt_addr_r}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi;\0" \ + "net_upgradeu=dhcp " BD_RAM_SCRIPT " net_upgradeu.scr && source " BD_RAM_SCRIPT "\0" \ + "otg_upgradeu=run usbnetwork; tftp " BD_RAM_SCRIPT " net_upgradeu.scr && source " BD_RAM_SCRIPT "\0" \ + "upgradeu=setenv boot_scripts upgrade.scr; boot;" \ + "echo Upgrade failed!; setenv boot_scripts boot.scr\0" \ + "usbnet_devaddr=00:19:b8:00:00:02\0" \ + "usbnet_hostaddr=00:19:b8:00:00:01\0" \ + "usbnetwork=setenv ethact usb_ether; " \ + "setenv ipaddr 10.0.0.2; " \ + "setenv netmask 255.255.255.0; " \ + "setenv serverip 10.0.0.1;\0" \ + BOOTENV + +/* + * PCI express + */ +#ifdef CONFIG_CMD_PCI +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_PCIE_IMX +#endif +#endif diff --git a/include/dwc3-uboot.h b/include/dwc3-uboot.h index 228ab3b10294..fe6fe8eb0e1a 100644 --- a/include/dwc3-uboot.h +++ b/include/dwc3-uboot.h @@ -15,6 +15,7 @@ struct dwc3_device { unsigned long base; enum usb_dr_mode dr_mode; u32 maximum_speed; + u16 power_down_scale; unsigned tx_fifo_resize:1; unsigned has_lpm_erratum; u8 lpm_nyet_threshold; diff --git a/include/i2c.h b/include/i2c.h index d33f827500b1..622dd316c68d 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -615,6 +615,7 @@ struct i2c_adapter { _set_speed, _speed, _slaveaddr, _hwadapnr, _name); struct i2c_adapter *i2c_get_adapter(int index); +struct i2c_adapter *i2c_get_adapter_valid(int index); #ifndef CONFIG_SYS_I2C_DIRECT_BUS struct i2c_mux { @@ -641,7 +642,7 @@ extern struct i2c_bus_hose i2c_bus[]; #endif #define I2C_BUS gd->cur_i2c_bus -#define I2C_ADAP_NR(bus) i2c_get_adapter(I2C_ADAPTER(bus)) +#define I2C_ADAP_NR(bus) i2c_get_adapter_valid(bus) #define I2C_ADAP I2C_ADAP_NR(gd->cur_i2c_bus) #define I2C_ADAP_HWNR (I2C_ADAP->hwadapnr) diff --git a/include/imx8_hdmi.h b/include/imx8_hdmi.h new file mode 100644 index 000000000000..eb1253cf51f2 --- /dev/null +++ b/include/imx8_hdmi.h @@ -0,0 +1,13 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __IMX8_HDMI_H__ +#define __IMX8_HDMI_H__ + +int imx8_hdmi_enable(int encoding, struct video_mode_settings *vms); +void imx8_hdmi_disable(void); + +#endif /* __IMX8_HDMI_H__*/ diff --git a/include/linux/sizes.h b/include/linux/sizes.h index ce3e8150c174..675e07f63ca2 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -44,4 +44,6 @@ #define SZ_1G 0x40000000 #define SZ_2G 0x80000000 +#define SZ_4G _AC(0x100000000, ULL) + #endif /* __LINUX_SIZES_H__ */ diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h index 9ceee0a1c9f6..c63a5f34c0ce 100644 --- a/include/linux/usb/dwc3.h +++ b/include/linux/usb/dwc3.h @@ -154,6 +154,7 @@ struct dwc3 { /* offset: 0xC100 */ /* Global Configuration Register */ #define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19) +#define DWC3_GCTL_PWRDNSCALE_MASK DWC3_GCTL_PWRDNSCALE(0x1fff) #define DWC3_GCTL_U2RSTECN (1 << 16) #define DWC3_GCTL_RAMCLKSEL(x) \ (((x) & DWC3_GCTL_CLK_MASK) << 6) diff --git a/lib/image-sparse.c b/lib/image-sparse.c index 036062139bb9..ef959f3cd9c0 100644 --- a/lib/image-sparse.c +++ b/lib/image-sparse.c @@ -62,6 +62,7 @@ int write_sparse_image(struct sparse_storage *info, chunk_header_t *chunk_header; uint32_t total_blocks = 0; int fill_buf_num_blks; + int dcache_enabled = dcache_status(); int i; int j; @@ -106,6 +107,10 @@ int write_sparse_image(struct sparse_storage *info, puts("Flashing Sparse Image\n"); + /* Disable data cache since chunks might not be aligned */ + if (dcache_enabled) + dcache_disable(); + /* Start processing chunks */ blk = info->start; for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) { @@ -248,6 +253,10 @@ int write_sparse_image(struct sparse_storage *info, } } + /* Re-enable data cache it in case it was in the first place */ + if (dcache_enabled) + dcache_enable(); + debug("Wrote %d blocks, expected to write %d blocks\n", total_blocks, sparse_header->total_blks); printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name); diff --git a/tools/imx8m_image.sh b/tools/imx8m_image.sh index 6346fb64d8c5..ec0881a12812 100755 --- a/tools/imx8m_image.sh +++ b/tools/imx8m_image.sh @@ -12,7 +12,7 @@ blobs=`awk '/^SIGNED_HDMI/ {print $2} /^LOADER/ {print $2} /^SECOND_LOADER/ {pri for f in $blobs; do tmp=$srctree/$f - if [ $f == "spl/u-boot-spl-ddr.bin" ] || [ $f == "u-boot.itb" ]; then + if [ $f = "spl/u-boot-spl-ddr.bin" ] || [ $f = "u-boot.itb" ]; then continue fi @@ -28,7 +28,7 @@ for f in $blobs; do sed -in "s;$f;$tmp;" $file done -if [ $post_process == 1 ]; then +if [ $post_process = 1 ]; then if [ -f $srctree/lpddr4_pmu_train_1d_imem.bin ]; then objcopy -I binary -O binary --pad-to 0x8000 --gap-fill=0x0 $srctree/lpddr4_pmu_train_1d_imem.bin lpddr4_pmu_train_1d_imem_pad.bin objcopy -I binary -O binary --pad-to 0x4000 --gap-fill=0x0 $srctree/lpddr4_pmu_train_1d_dmem.bin lpddr4_pmu_train_1d_dmem_pad.bin