Home | History | Annotate | Line # | Download | only in ic
      1  1.3  riastrad /* $NetBSD: dw_hdmi_phy.c,v 1.3 2021/12/19 11:00:47 riastradh Exp $ */
      2  1.1  jmcneill 
      3  1.1  jmcneill /*-
      4  1.1  jmcneill  * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo (at) freebsd.org>
      5  1.1  jmcneill  * All rights reserved.
      6  1.1  jmcneill  *
      7  1.1  jmcneill  * Redistribution and use in source and binary forms, with or without
      8  1.1  jmcneill  * modification, are permitted provided that the following conditions
      9  1.1  jmcneill  * are met:
     10  1.1  jmcneill  * 1. Redistributions of source code must retain the above copyright
     11  1.1  jmcneill  *    notice, this list of conditions and the following disclaimer.
     12  1.1  jmcneill  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jmcneill  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  jmcneill  *    documentation and/or other materials provided with the distribution.
     15  1.1  jmcneill  *
     16  1.1  jmcneill  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  1.1  jmcneill  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1  jmcneill  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1  jmcneill  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  1.1  jmcneill  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  1.1  jmcneill  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  1.1  jmcneill  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  1.1  jmcneill  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  1.1  jmcneill  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.1  jmcneill  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.1  jmcneill  * SUCH DAMAGE.
     27  1.1  jmcneill  */
     28  1.1  jmcneill 
     29  1.1  jmcneill #include <sys/cdefs.h>
     30  1.3  riastrad __KERNEL_RCSID(0, "$NetBSD: dw_hdmi_phy.c,v 1.3 2021/12/19 11:00:47 riastradh Exp $");
     31  1.1  jmcneill 
     32  1.1  jmcneill #include <sys/param.h>
     33  1.1  jmcneill 
     34  1.3  riastrad #include <drm/drm_drv.h>
     35  1.1  jmcneill 
     36  1.1  jmcneill #include <dev/ic/dw_hdmi.h>
     37  1.1  jmcneill 
     38  1.1  jmcneill #define	HDMI_IH_PHY_STAT0                       0x0104
     39  1.1  jmcneill #define	  HDMI_IH_PHY_STAT0_HPD (1 << 0)
     40  1.1  jmcneill #define	HDMI_IH_I2CMPHY_STAT0                   0x0108
     41  1.1  jmcneill #define	  HDMI_IH_I2CMPHY_STAT0_DONE            (1 << 1)
     42  1.1  jmcneill #define	  HDMI_IH_I2CMPHY_STAT0_ERROR           (1 << 0)
     43  1.1  jmcneill 
     44  1.1  jmcneill #define	HDMI_PHY_CONF0				0x3000
     45  1.1  jmcneill #define	  HDMI_PHY_CONF0_PDZ_MASK			0x80
     46  1.1  jmcneill #define	  HDMI_PHY_CONF0_PDZ_OFFSET		7
     47  1.1  jmcneill #define	  HDMI_PHY_CONF0_ENTMDS_MASK		0x40
     48  1.1  jmcneill #define	  HDMI_PHY_CONF0_ENTMDS_OFFSET		6
     49  1.1  jmcneill #define	  HDMI_PHY_CONF0_SVSRET_MASK		0x20
     50  1.1  jmcneill #define	  HDMI_PHY_CONF0_SVSRET_OFFSET			5
     51  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_PDDQ_MASK		0x10
     52  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET		4
     53  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_TXPWRON_MASK	0x8
     54  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET	3
     55  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK	0x4
     56  1.1  jmcneill #define	  HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET	2
     57  1.1  jmcneill #define	  HDMI_PHY_CONF0_SELDATAENPOL_MASK	0x2
     58  1.1  jmcneill #define	  HDMI_PHY_CONF0_SELDATAENPOL_OFFSET	1
     59  1.1  jmcneill #define	  HDMI_PHY_CONF0_SELDIPIF_MASK		0x1
     60  1.1  jmcneill #define	  HDMI_PHY_CONF0_SELDIPIF_OFFSET		0
     61  1.1  jmcneill #define	HDMI_PHY_TST0				0x3001
     62  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTCLR_MASK		0x20
     63  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTCLR_OFFSET		5
     64  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTEN_MASK		0x10
     65  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTEN_OFFSET		4
     66  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTCLK_MASK		0x1
     67  1.1  jmcneill #define	  HDMI_PHY_TST0_TSTCLK_OFFSET		0
     68  1.1  jmcneill #define	HDMI_PHY_TST1				0x3002
     69  1.1  jmcneill #define	HDMI_PHY_TST2				0x3003
     70  1.1  jmcneill #define	HDMI_PHY_STAT0				0x3004
     71  1.1  jmcneill #define	  HDMI_PHY_STAT0_RX_SENSE3		0x80
     72  1.1  jmcneill #define	  HDMI_PHY_STAT0_RX_SENSE2		0x40
     73  1.1  jmcneill #define	  HDMI_PHY_STAT0_RX_SENSE1		0x20
     74  1.1  jmcneill #define	  HDMI_PHY_STAT0_RX_SENSE0		0x10
     75  1.1  jmcneill #define	  HDMI_PHY_STAT0_RX_SENSE		0xf0
     76  1.1  jmcneill #define	  HDMI_PHY_STAT0_HPD			0x02
     77  1.1  jmcneill #define	  HDMI_PHY_TX_PHY_LOCK			0x01
     78  1.1  jmcneill #define	HDMI_PHY_INT0				0x3005
     79  1.1  jmcneill #define	HDMI_PHY_MASK0				0x3006
     80  1.1  jmcneill #define	HDMI_PHY_POL0				0x3007
     81  1.1  jmcneill #define	  HDMI_PHY_POL0_HPD			0x02
     82  1.1  jmcneill 
     83  1.1  jmcneill /* HDMI Master PHY Registers */
     84  1.1  jmcneill #define	HDMI_PHY_I2CM_SLAVE_ADDR		0x3020
     85  1.1  jmcneill #define	  HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2	0x69
     86  1.1  jmcneill #define	  HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY	0x49
     87  1.1  jmcneill #define	HDMI_PHY_I2CM_ADDRESS_ADDR		0x3021
     88  1.1  jmcneill #define	HDMI_PHY_I2CM_DATAO_1_ADDR		0x3022
     89  1.1  jmcneill #define	HDMI_PHY_I2CM_DATAO_0_ADDR		0x3023
     90  1.1  jmcneill #define	HDMI_PHY_I2CM_DATAI_1_ADDR		0x3024
     91  1.1  jmcneill #define	HDMI_PHY_I2CM_DATAI_0_ADDR		0x3025
     92  1.1  jmcneill #define	HDMI_PHY_I2CM_OPERATION_ADDR		0x3026
     93  1.1  jmcneill #define	  HDMI_PHY_I2CM_OPERATION_ADDR_WRITE    0x10
     94  1.1  jmcneill #define	  HDMI_PHY_I2CM_OPERATION_ADDR_READ     0x1
     95  1.1  jmcneill #define	HDMI_PHY_I2CM_INT_ADDR			0x3027
     96  1.1  jmcneill #define	HDMI_PHY_I2CM_CTLINT_ADDR		0x3028
     97  1.1  jmcneill #define	HDMI_PHY_I2CM_DIV_ADDR			0x3029
     98  1.1  jmcneill #define	HDMI_PHY_I2CM_SOFTRSTZ_ADDR		0x302a
     99  1.1  jmcneill #define	HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR	0x302b
    100  1.1  jmcneill #define	HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR	0x302c
    101  1.1  jmcneill #define	HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR	0x302d
    102  1.1  jmcneill #define	HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR	0x302e
    103  1.1  jmcneill #define	HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR	0x302f
    104  1.1  jmcneill #define	HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR	0x3030
    105  1.1  jmcneill #define	HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR	0x3031
    106  1.1  jmcneill #define	HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR	0x3032
    107  1.1  jmcneill 
    108  1.1  jmcneill #define	HDMI_MC_FLOWCTRL                        0x4004
    109  1.1  jmcneill #define	  HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK                0x1
    110  1.1  jmcneill #define	  HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH 0x1
    111  1.1  jmcneill #define	  HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS  0x0
    112  1.1  jmcneill #define	HDMI_MC_PHYRSTZ                         0x4005
    113  1.1  jmcneill #define	  HDMI_MC_PHYRSTZ_ASSERT                        0x0
    114  1.1  jmcneill #define	  HDMI_MC_PHYRSTZ_DEASSERT              0x1
    115  1.1  jmcneill #define	HDMI_MC_HEACPHY_RST                     0x4007
    116  1.1  jmcneill #define	  HDMI_MC_HEACPHY_RST_ASSERT            0x1
    117  1.1  jmcneill #define	  HDMI_MC_HEACPHY_RST_DEASSERT          0x0
    118  1.1  jmcneill 
    119  1.1  jmcneill /* HDMI PHY register with access through I2C */
    120  1.1  jmcneill #define	HDMI_PHY_I2C_CKCALCTRL	0x5
    121  1.1  jmcneill #define	  CKCALCTRL_OVERRIDE	(1 << 15)
    122  1.1  jmcneill #define	HDMI_PHY_I2C_CPCE_CTRL	0x6
    123  1.1  jmcneill #define	  CPCE_CTRL_45_25		((3 << 7) | (3 << 5))
    124  1.1  jmcneill #define	  CPCE_CTRL_92_50		((2 << 7) | (2 << 5))
    125  1.1  jmcneill #define	  CPCE_CTRL_185		((1 << 7) | (1 << 5))
    126  1.1  jmcneill #define	  CPCE_CTRL_370		((0 << 7) | (0 << 5))
    127  1.1  jmcneill #define	HDMI_PHY_I2C_CKSYMTXCTRL	0x9
    128  1.1  jmcneill #define	  CKSYMTXCTRL_OVERRIDE	(1 << 15)
    129  1.1  jmcneill #define	  CKSYMTXCTRL_TX_SYMON	(1 << 3)
    130  1.1  jmcneill #define	  CKSYMTXCTRL_TX_TRAON	(1 << 2)
    131  1.1  jmcneill #define	  CKSYMTXCTRL_TX_TRBON	(1 << 1)
    132  1.1  jmcneill #define	  CKSYMTXCTRL_TX_CK_SYMON	(1 << 0)
    133  1.1  jmcneill #define	HDMI_PHY_I2C_VLEVCTRL		0x0E
    134  1.1  jmcneill #define	HDMI_PHY_I2C_CURRCTRL		0x10
    135  1.1  jmcneill #define	HDMI_PHY_I2C_PLLPHBYCTRL	0x13
    136  1.1  jmcneill #define	  VLEVCTRL_TX_LVL(x)	((x) << 5)
    137  1.1  jmcneill #define	  VLEVCTRL_CK_LVL(x)	(x)
    138  1.1  jmcneill #define	HDMI_PHY_I2C_GMPCTRL	0x15
    139  1.1  jmcneill #define	  GMPCTRL_45_25		0x00
    140  1.1  jmcneill #define	  GMPCTRL_92_50		0x05
    141  1.1  jmcneill #define	  GMPCTRL_185		0x0a
    142  1.1  jmcneill #define	  GMPCTRL_370		0x0f
    143  1.1  jmcneill #define	HDMI_PHY_I2C_MSM_CTRL	0x17
    144  1.1  jmcneill #define	  MSM_CTRL_FB_CLK		(0x3 << 1)
    145  1.1  jmcneill #define	HDMI_PHY_I2C_TXTERM	0x19
    146  1.1  jmcneill #define	  TXTERM_133		0x5
    147  1.1  jmcneill 
    148  1.1  jmcneill static void
    149  1.1  jmcneill dwhdmi_phy_wait_i2c_done(struct dwhdmi_softc *sc, int msec)
    150  1.1  jmcneill {
    151  1.1  jmcneill 	uint8_t val;
    152  1.1  jmcneill 
    153  1.1  jmcneill 	val = dwhdmi_read(sc, HDMI_IH_I2CMPHY_STAT0) &
    154  1.1  jmcneill 	    (HDMI_IH_I2CMPHY_STAT0_DONE | HDMI_IH_I2CMPHY_STAT0_ERROR);
    155  1.1  jmcneill 	while (val == 0) {
    156  1.1  jmcneill 		delay(1000);
    157  1.1  jmcneill 		msec -= 10;
    158  1.1  jmcneill 		if (msec <= 0)
    159  1.1  jmcneill 			return;
    160  1.1  jmcneill 		val = dwhdmi_read(sc, HDMI_IH_I2CMPHY_STAT0) &
    161  1.1  jmcneill 		    (HDMI_IH_I2CMPHY_STAT0_DONE | HDMI_IH_I2CMPHY_STAT0_ERROR);
    162  1.1  jmcneill 	}
    163  1.1  jmcneill }
    164  1.1  jmcneill 
    165  1.1  jmcneill static void
    166  1.1  jmcneill dwhdmi_phy_i2c_write(struct dwhdmi_softc *sc, unsigned short data,
    167  1.1  jmcneill     unsigned char addr)
    168  1.1  jmcneill {
    169  1.1  jmcneill 
    170  1.1  jmcneill 	/* clear DONE and ERROR flags */
    171  1.1  jmcneill 	dwhdmi_write(sc, HDMI_IH_I2CMPHY_STAT0,
    172  1.1  jmcneill 	    HDMI_IH_I2CMPHY_STAT0_DONE | HDMI_IH_I2CMPHY_STAT0_ERROR);
    173  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_I2CM_ADDRESS_ADDR, addr);
    174  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_I2CM_DATAO_1_ADDR, ((data >> 8) & 0xff));
    175  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_I2CM_DATAO_0_ADDR, ((data >> 0) & 0xff));
    176  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_I2CM_OPERATION_ADDR, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE);
    177  1.1  jmcneill 	dwhdmi_phy_wait_i2c_done(sc, 1000);
    178  1.1  jmcneill }
    179  1.1  jmcneill 
    180  1.1  jmcneill static void
    181  1.1  jmcneill dwhdmi_phy_enable_power(struct dwhdmi_softc *sc, uint8_t enable)
    182  1.1  jmcneill {
    183  1.1  jmcneill 	uint8_t reg;
    184  1.1  jmcneill 
    185  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    186  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_PDZ_MASK;
    187  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_PDZ_OFFSET);
    188  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    189  1.1  jmcneill }
    190  1.1  jmcneill 
    191  1.1  jmcneill static void
    192  1.1  jmcneill dwhdmi_phy_enable_tmds(struct dwhdmi_softc *sc, uint8_t enable)
    193  1.1  jmcneill {
    194  1.1  jmcneill 	uint8_t reg;
    195  1.1  jmcneill 
    196  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    197  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_ENTMDS_MASK;
    198  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
    199  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    200  1.1  jmcneill }
    201  1.1  jmcneill 
    202  1.1  jmcneill static void
    203  1.1  jmcneill dwhdmi_phy_gen2_pddq(struct dwhdmi_softc *sc, uint8_t enable)
    204  1.1  jmcneill {
    205  1.1  jmcneill 	uint8_t reg;
    206  1.1  jmcneill 
    207  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    208  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_GEN2_PDDQ_MASK;
    209  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
    210  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    211  1.1  jmcneill }
    212  1.1  jmcneill 
    213  1.1  jmcneill static void
    214  1.1  jmcneill dwhdmi_phy_gen2_txpwron(struct dwhdmi_softc *sc, uint8_t enable)
    215  1.1  jmcneill {
    216  1.1  jmcneill 	uint8_t reg;
    217  1.1  jmcneill 
    218  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    219  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
    220  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
    221  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    222  1.1  jmcneill }
    223  1.1  jmcneill 
    224  1.1  jmcneill static void
    225  1.1  jmcneill dwhdmi_phy_sel_data_en_pol(struct dwhdmi_softc *sc, uint8_t enable)
    226  1.1  jmcneill {
    227  1.1  jmcneill 	uint8_t reg;
    228  1.1  jmcneill 
    229  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    230  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_SELDATAENPOL_MASK;
    231  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
    232  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    233  1.1  jmcneill }
    234  1.1  jmcneill 
    235  1.1  jmcneill static void
    236  1.1  jmcneill dwhdmi_phy_sel_interface_control(struct dwhdmi_softc *sc, uint8_t enable)
    237  1.1  jmcneill {
    238  1.1  jmcneill 	uint8_t reg;
    239  1.1  jmcneill 
    240  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    241  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_SELDIPIF_MASK;
    242  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
    243  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    244  1.1  jmcneill }
    245  1.1  jmcneill 
    246  1.1  jmcneill static void
    247  1.1  jmcneill dwhdmi_phy_enable_svsret(struct dwhdmi_softc *sc, uint8_t enable)
    248  1.1  jmcneill {
    249  1.1  jmcneill 	uint8_t reg;
    250  1.1  jmcneill 
    251  1.1  jmcneill 	reg = dwhdmi_read(sc, HDMI_PHY_CONF0);
    252  1.1  jmcneill 	reg &= ~HDMI_PHY_CONF0_SVSRET_MASK;
    253  1.1  jmcneill 	reg |= (enable << HDMI_PHY_CONF0_SVSRET_OFFSET);
    254  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_CONF0, reg);
    255  1.1  jmcneill }
    256  1.1  jmcneill 
    257  1.1  jmcneill static inline void
    258  1.1  jmcneill dwhdmi_phy_test_clear(struct dwhdmi_softc *sc, unsigned char bit)
    259  1.1  jmcneill {
    260  1.1  jmcneill 	uint8_t val;
    261  1.1  jmcneill 
    262  1.1  jmcneill 	val = dwhdmi_read(sc, HDMI_PHY_TST0);
    263  1.1  jmcneill 	val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
    264  1.1  jmcneill 	val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
    265  1.1  jmcneill 		HDMI_PHY_TST0_TSTCLR_MASK;
    266  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_TST0, val);
    267  1.1  jmcneill }
    268  1.1  jmcneill 
    269  1.1  jmcneill static int
    270  1.3  riastrad dwhdmi_phy_configure(struct dwhdmi_softc *sc, const struct drm_display_mode *mode)
    271  1.1  jmcneill {
    272  1.1  jmcneill 	const struct dwhdmi_mpll_config *mpll_conf;
    273  1.1  jmcneill 	const struct dwhdmi_phy_config *phy_conf;
    274  1.1  jmcneill 	uint8_t val;
    275  1.1  jmcneill 	uint8_t msec;
    276  1.1  jmcneill 
    277  1.1  jmcneill 	dwhdmi_write(sc, HDMI_MC_FLOWCTRL, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS);
    278  1.1  jmcneill 
    279  1.1  jmcneill 	/* gen2 tx power off */
    280  1.1  jmcneill 	dwhdmi_phy_gen2_txpwron(sc, 0);
    281  1.1  jmcneill 
    282  1.1  jmcneill 	/* gen2 pddq */
    283  1.1  jmcneill 	dwhdmi_phy_gen2_pddq(sc, 1);
    284  1.1  jmcneill 
    285  1.1  jmcneill 	/* PHY reset */
    286  1.1  jmcneill 	dwhdmi_write(sc, HDMI_MC_PHYRSTZ, HDMI_MC_PHYRSTZ_DEASSERT);
    287  1.1  jmcneill 	dwhdmi_write(sc, HDMI_MC_PHYRSTZ, HDMI_MC_PHYRSTZ_ASSERT);
    288  1.1  jmcneill 
    289  1.1  jmcneill 	dwhdmi_write(sc, HDMI_MC_HEACPHY_RST, HDMI_MC_HEACPHY_RST_ASSERT);
    290  1.1  jmcneill 
    291  1.1  jmcneill 	dwhdmi_phy_test_clear(sc, 1);
    292  1.1  jmcneill 	dwhdmi_write(sc, HDMI_PHY_I2CM_SLAVE_ADDR, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
    293  1.1  jmcneill 	dwhdmi_phy_test_clear(sc, 0);
    294  1.1  jmcneill 
    295  1.1  jmcneill 	/*
    296  1.1  jmcneill 	 * Following initialization are for 8bit per color case
    297  1.1  jmcneill 	 */
    298  1.1  jmcneill 
    299  1.1  jmcneill 	/*
    300  1.1  jmcneill 	 * PLL/MPLL config
    301  1.1  jmcneill 	 */
    302  1.1  jmcneill 	for (mpll_conf = &sc->sc_mpll_config[0]; mpll_conf->pixel_clock != 0; mpll_conf++)
    303  1.2  jmcneill 		if (mode->clock <= mpll_conf->pixel_clock)
    304  1.1  jmcneill 			break;
    305  1.1  jmcneill 
    306  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, mpll_conf->cpce, HDMI_PHY_I2C_CPCE_CTRL);
    307  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, mpll_conf->gmp, HDMI_PHY_I2C_GMPCTRL);
    308  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, mpll_conf->curr, HDMI_PHY_I2C_CURRCTRL);
    309  1.1  jmcneill 
    310  1.1  jmcneill 	for (phy_conf = &sc->sc_phy_config[0]; phy_conf->pixel_clock != 0; phy_conf++)
    311  1.2  jmcneill 		if (mode->clock <= phy_conf->pixel_clock)
    312  1.1  jmcneill 			break;
    313  1.1  jmcneill 
    314  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, 0x0000, HDMI_PHY_I2C_PLLPHBYCTRL);
    315  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, MSM_CTRL_FB_CLK, HDMI_PHY_I2C_MSM_CTRL);
    316  1.1  jmcneill 
    317  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, phy_conf->term, HDMI_PHY_I2C_TXTERM);
    318  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, phy_conf->sym, HDMI_PHY_I2C_CKSYMTXCTRL);
    319  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, phy_conf->vlev, HDMI_PHY_I2C_VLEVCTRL);
    320  1.1  jmcneill 
    321  1.1  jmcneill 	/* REMOVE CLK TERM */
    322  1.1  jmcneill 	dwhdmi_phy_i2c_write(sc, CKCALCTRL_OVERRIDE, HDMI_PHY_I2C_CKCALCTRL);
    323  1.1  jmcneill 
    324  1.1  jmcneill 	dwhdmi_phy_enable_power(sc, 1);
    325  1.1  jmcneill 
    326  1.1  jmcneill 	/* toggle TMDS enable */
    327  1.1  jmcneill 	dwhdmi_phy_enable_tmds(sc, 0);
    328  1.1  jmcneill 	dwhdmi_phy_enable_tmds(sc, 1);
    329  1.1  jmcneill 
    330  1.1  jmcneill 	/* gen2 tx power on */
    331  1.1  jmcneill 	dwhdmi_phy_gen2_txpwron(sc, 1);
    332  1.1  jmcneill 	dwhdmi_phy_gen2_pddq(sc, 0);
    333  1.1  jmcneill 
    334  1.1  jmcneill 	switch (sc->sc_phytype) {
    335  1.1  jmcneill 	case 0xb2:	/* MHL PHY HEAC */
    336  1.1  jmcneill 	case 0xc2:	/* MHL PHY */
    337  1.1  jmcneill 	case 0xf3:	/* HDMI 2.0 TX PHY */
    338  1.1  jmcneill 		dwhdmi_phy_enable_svsret(sc, 1);
    339  1.1  jmcneill 		break;
    340  1.1  jmcneill 	}
    341  1.1  jmcneill 
    342  1.1  jmcneill 	/*Wait for PHY PLL lock */
    343  1.1  jmcneill 	msec = 4;
    344  1.1  jmcneill 	val = dwhdmi_read(sc, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
    345  1.1  jmcneill 	while (val == 0) {
    346  1.1  jmcneill 		delay(1000);
    347  1.1  jmcneill 		if (msec-- == 0) {
    348  1.1  jmcneill 			device_printf(sc->sc_dev, "PHY PLL not locked\n");
    349  1.1  jmcneill 			return (-1);
    350  1.1  jmcneill 		}
    351  1.1  jmcneill 		val = dwhdmi_read(sc, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
    352  1.1  jmcneill 	}
    353  1.1  jmcneill 
    354  1.1  jmcneill 	return (0);
    355  1.1  jmcneill }
    356  1.1  jmcneill 
    357  1.1  jmcneill static void
    358  1.3  riastrad dwhdmi_phy_init(struct dwhdmi_softc *sc, const struct drm_display_mode *mode)
    359  1.1  jmcneill {
    360  1.1  jmcneill 	int i;
    361  1.1  jmcneill 
    362  1.1  jmcneill 	/* HDMI Phy spec says to do the phy initialization sequence twice */
    363  1.1  jmcneill 	for (i = 0 ; i < 2 ; i++) {
    364  1.1  jmcneill 		dwhdmi_phy_sel_data_en_pol(sc, 1);
    365  1.1  jmcneill 		dwhdmi_phy_sel_interface_control(sc, 0);
    366  1.1  jmcneill 		dwhdmi_phy_enable_tmds(sc, 0);
    367  1.1  jmcneill 		dwhdmi_phy_enable_power(sc, 0);
    368  1.1  jmcneill 
    369  1.1  jmcneill 		/* Enable CSC */
    370  1.1  jmcneill 		dwhdmi_phy_configure(sc, mode);
    371  1.1  jmcneill 	}
    372  1.1  jmcneill }
    373  1.1  jmcneill 
    374  1.1  jmcneill enum drm_connector_status
    375  1.1  jmcneill dwhdmi_phy_detect(struct dwhdmi_softc *sc, bool force)
    376  1.1  jmcneill {
    377  1.1  jmcneill 	uint8_t val;
    378  1.1  jmcneill 
    379  1.1  jmcneill 	val = dwhdmi_read(sc, HDMI_PHY_STAT0);
    380  1.1  jmcneill 
    381  1.1  jmcneill 	return ((val & HDMI_PHY_STAT0_HPD) != 0) ?
    382  1.1  jmcneill 	    connector_status_connected :
    383  1.1  jmcneill 	    connector_status_disconnected;
    384  1.1  jmcneill }
    385  1.1  jmcneill 
    386  1.1  jmcneill void
    387  1.1  jmcneill dwhdmi_phy_enable(struct dwhdmi_softc *sc)
    388  1.1  jmcneill {
    389  1.1  jmcneill }
    390  1.1  jmcneill 
    391  1.1  jmcneill void
    392  1.1  jmcneill dwhdmi_phy_disable(struct dwhdmi_softc *sc)
    393  1.1  jmcneill {
    394  1.1  jmcneill }
    395  1.1  jmcneill 
    396  1.1  jmcneill void
    397  1.1  jmcneill dwhdmi_phy_mode_set(struct dwhdmi_softc *sc,
    398  1.3  riastrad     const struct drm_display_mode *mode,
    399  1.3  riastrad     const struct drm_display_mode *adjusted_mode)
    400  1.1  jmcneill {
    401  1.1  jmcneill 	dwhdmi_phy_init(sc, adjusted_mode);
    402  1.1  jmcneill }
    403