cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ddk750_sii164.c (11138B)


      1// SPDX-License-Identifier: GPL-2.0
      2#define USE_DVICHIP
      3#ifdef USE_DVICHIP
      4
      5#include "ddk750_sii164.h"
      6#include "ddk750_hwi2c.h"
      7
      8/* I2C Address of each SII164 chip */
      9#define SII164_I2C_ADDRESS                  0x70
     10
     11/* Define this definition to use hardware i2c. */
     12#define USE_HW_I2C
     13
     14#ifdef USE_HW_I2C
     15    #define i2cWriteReg sm750_hw_i2c_write_reg
     16    #define i2cReadReg  sm750_hw_i2c_read_reg
     17#else
     18    #define i2cWriteReg sm750_sw_i2c_write_reg
     19    #define i2cReadReg  sm750_sw_i2c_read_reg
     20#endif
     21
     22/* SII164 Vendor and Device ID */
     23#define SII164_VENDOR_ID                    0x0001
     24#define SII164_DEVICE_ID                    0x0006
     25
     26#ifdef SII164_FULL_FUNCTIONS
     27/* Name of the DVI Controller chip */
     28static char *gDviCtrlChipName = "Silicon Image SiI 164";
     29#endif
     30
     31/*
     32 *  sii164GetVendorID
     33 *      This function gets the vendor ID of the DVI controller chip.
     34 *
     35 *  Output:
     36 *      Vendor ID
     37 */
     38unsigned short sii164GetVendorID(void)
     39{
     40	unsigned short vendorID;
     41
     42	vendorID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS,
     43					       SII164_VENDOR_ID_HIGH) << 8) |
     44		   (unsigned short)i2cReadReg(SII164_I2C_ADDRESS,
     45					      SII164_VENDOR_ID_LOW);
     46
     47	return vendorID;
     48}
     49
     50/*
     51 *  sii164GetDeviceID
     52 *      This function gets the device ID of the DVI controller chip.
     53 *
     54 *  Output:
     55 *      Device ID
     56 */
     57unsigned short sii164GetDeviceID(void)
     58{
     59	unsigned short deviceID;
     60
     61	deviceID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS,
     62					       SII164_DEVICE_ID_HIGH) << 8) |
     63		   (unsigned short)i2cReadReg(SII164_I2C_ADDRESS,
     64					      SII164_DEVICE_ID_LOW);
     65
     66	return deviceID;
     67}
     68
     69/*
     70 *  DVI.C will handle all SiI164 chip stuffs and try its best to make code
     71 *  minimal and useful
     72 */
     73
     74/*
     75 *  sii164InitChip
     76 *      This function initialize and detect the DVI controller chip.
     77 *
     78 *  Input:
     79 *      edge_select           - Edge Select:
     80 *                               0 = Input data is falling edge latched (falling
     81 *                                   edge latched first in dual edge mode)
     82 *                               1 = Input data is rising edge latched (rising
     83 *                                   edge latched first in dual edge mode)
     84 *      bus_select            - Input Bus Select:
     85 *                               0 = Input data bus is 12-bits wide
     86 *                               1 = Input data bus is 24-bits wide
     87 *      dual_edge_clk_select  - Dual Edge Clock Select
     88 *                               0 = Input data is single edge latched
     89 *                               1 = Input data is dual edge latched
     90 *      hsync_enable          - Horizontal Sync Enable:
     91 *                               0 = HSYNC input is transmitted as fixed LOW
     92 *                               1 = HSYNC input is transmitted as is
     93 *      vsync_enable          - Vertical Sync Enable:
     94 *                               0 = VSYNC input is transmitted as fixed LOW
     95 *                               1 = VSYNC input is transmitted as is
     96 *      deskew_enable         - De-skewing Enable:
     97 *                               0 = De-skew disabled
     98 *                               1 = De-skew enabled
     99 *      deskew_setting        - De-skewing Setting (increment of 260psec)
    100 *                               0 = 1 step --> minimum setup / maximum hold
    101 *                               1 = 2 step
    102 *                               2 = 3 step
    103 *                               3 = 4 step
    104 *                               4 = 5 step
    105 *                               5 = 6 step
    106 *                               6 = 7 step
    107 *                               7 = 8 step --> maximum setup / minimum hold
    108 *      continuous_sync_enable- SYNC Continuous:
    109 *                               0 = Disable
    110 *                               1 = Enable
    111 *      pll_filter_enable     - PLL Filter Enable
    112 *                               0 = Disable PLL Filter
    113 *                               1 = Enable PLL Filter
    114 *      pll_filter_value      - PLL Filter characteristics:
    115 *                               0~7 (recommended value is 4)
    116 *
    117 *  Output:
    118 *      0   - Success
    119 *     -1   - Fail.
    120 */
    121long sii164InitChip(unsigned char edge_select,
    122		    unsigned char bus_select,
    123		    unsigned char dual_edge_clk_select,
    124		    unsigned char hsync_enable,
    125		    unsigned char vsync_enable,
    126		    unsigned char deskew_enable,
    127		    unsigned char deskew_setting,
    128		    unsigned char continuous_sync_enable,
    129		    unsigned char pll_filter_enable,
    130		    unsigned char pll_filter_value)
    131{
    132	unsigned char config;
    133
    134	/* Initialize the i2c bus */
    135#ifdef USE_HW_I2C
    136	/* Use fast mode. */
    137	sm750_hw_i2c_init(1);
    138#else
    139	sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
    140#endif
    141
    142	/* Check if SII164 Chip exists */
    143	if ((sii164GetVendorID() == SII164_VENDOR_ID) &&
    144	    (sii164GetDeviceID() == SII164_DEVICE_ID)) {
    145		/*
    146		 *  Initialize SII164 controller chip.
    147		 */
    148
    149		/* Select the edge */
    150		if (edge_select == 0)
    151			config = SII164_CONFIGURATION_LATCH_FALLING;
    152		else
    153			config = SII164_CONFIGURATION_LATCH_RISING;
    154
    155		/* Select bus wide */
    156		if (bus_select == 0)
    157			config |= SII164_CONFIGURATION_BUS_12BITS;
    158		else
    159			config |= SII164_CONFIGURATION_BUS_24BITS;
    160
    161		/* Select Dual/Single Edge Clock */
    162		if (dual_edge_clk_select == 0)
    163			config |= SII164_CONFIGURATION_CLOCK_SINGLE;
    164		else
    165			config |= SII164_CONFIGURATION_CLOCK_DUAL;
    166
    167		/* Select HSync Enable */
    168		if (hsync_enable == 0)
    169			config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
    170		else
    171			config |= SII164_CONFIGURATION_HSYNC_AS_IS;
    172
    173		/* Select VSync Enable */
    174		if (vsync_enable == 0)
    175			config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
    176		else
    177			config |= SII164_CONFIGURATION_VSYNC_AS_IS;
    178
    179		i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
    180
    181		/*
    182		 * De-skew enabled with default 111b value.
    183		 * This fixes some artifacts problem in some mode on board 2.2.
    184		 * Somehow this fix does not affect board 2.1.
    185		 */
    186		if (deskew_enable == 0)
    187			config = SII164_DESKEW_DISABLE;
    188		else
    189			config = SII164_DESKEW_ENABLE;
    190
    191		switch (deskew_setting) {
    192		case 0:
    193			config |= SII164_DESKEW_1_STEP;
    194			break;
    195		case 1:
    196			config |= SII164_DESKEW_2_STEP;
    197			break;
    198		case 2:
    199			config |= SII164_DESKEW_3_STEP;
    200			break;
    201		case 3:
    202			config |= SII164_DESKEW_4_STEP;
    203			break;
    204		case 4:
    205			config |= SII164_DESKEW_5_STEP;
    206			break;
    207		case 5:
    208			config |= SII164_DESKEW_6_STEP;
    209			break;
    210		case 6:
    211			config |= SII164_DESKEW_7_STEP;
    212			break;
    213		case 7:
    214			config |= SII164_DESKEW_8_STEP;
    215			break;
    216		}
    217		i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
    218
    219		/* Enable/Disable Continuous Sync. */
    220		if (continuous_sync_enable == 0)
    221			config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
    222		else
    223			config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
    224
    225		/* Enable/Disable PLL Filter */
    226		if (pll_filter_enable == 0)
    227			config |= SII164_PLL_FILTER_DISABLE;
    228		else
    229			config |= SII164_PLL_FILTER_ENABLE;
    230
    231		/* Set the PLL Filter value */
    232		config |= ((pll_filter_value & 0x07) << 1);
    233
    234		i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
    235
    236		/* Recover from Power Down and enable output. */
    237		config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
    238		config |= SII164_CONFIGURATION_POWER_NORMAL;
    239		i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
    240
    241		return 0;
    242	}
    243
    244	/* Return -1 if initialization fails. */
    245	return -1;
    246}
    247
    248/* below sii164 function is not necessary */
    249
    250#ifdef SII164_FULL_FUNCTIONS
    251
    252/*
    253 *  sii164ResetChip
    254 *      This function resets the DVI Controller Chip.
    255 */
    256void sii164ResetChip(void)
    257{
    258	/* Power down */
    259	sii164SetPower(0);
    260	sii164SetPower(1);
    261}
    262
    263/*
    264 * sii164GetChipString
    265 *      This function returns a char string name of the current DVI Controller
    266 *      chip.
    267 *
    268 *      It's convenient for application need to display the chip name.
    269 */
    270char *sii164GetChipString(void)
    271{
    272	return gDviCtrlChipName;
    273}
    274
    275/*
    276 *  sii164SetPower
    277 *      This function sets the power configuration of the DVI Controller Chip.
    278 *
    279 *  Input:
    280 *      powerUp - Flag to set the power down or up
    281 */
    282void sii164SetPower(unsigned char powerUp)
    283{
    284	unsigned char config;
    285
    286	config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
    287	if (powerUp == 1) {
    288		/* Power up the chip */
    289		config &= ~SII164_CONFIGURATION_POWER_MASK;
    290		config |= SII164_CONFIGURATION_POWER_NORMAL;
    291		i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
    292	} else {
    293		/* Power down the chip */
    294		config &= ~SII164_CONFIGURATION_POWER_MASK;
    295		config |= SII164_CONFIGURATION_POWER_DOWN;
    296		i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
    297	}
    298}
    299
    300/*
    301 *  sii164SelectHotPlugDetectionMode
    302 *      This function selects the mode of the hot plug detection.
    303 */
    304static
    305void sii164SelectHotPlugDetectionMode(enum sii164_hot_plug_mode hotPlugMode)
    306{
    307	unsigned char detectReg;
    308
    309	detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
    310		    ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
    311	switch (hotPlugMode) {
    312	case SII164_HOTPLUG_DISABLE:
    313		detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
    314		break;
    315	case SII164_HOTPLUG_USE_MDI:
    316		detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
    317		detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
    318		detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
    319		break;
    320	case SII164_HOTPLUG_USE_RSEN:
    321		detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
    322		break;
    323	case SII164_HOTPLUG_USE_HTPLG:
    324		detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
    325		break;
    326	}
    327
    328	i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
    329}
    330
    331/*
    332 *  sii164EnableHotPlugDetection
    333 *      This function enables the Hot Plug detection.
    334 *
    335 *  enableHotPlug   - Enable (=1) / disable (=0) Hot Plug detection
    336 */
    337void sii164EnableHotPlugDetection(unsigned char enableHotPlug)
    338{
    339	unsigned char detectReg;
    340
    341	detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
    342
    343	/* Depending on each DVI controller, need to enable the hot plug based
    344	 * on each individual chip design.
    345	 */
    346	if (enableHotPlug != 0)
    347		sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
    348	else
    349		sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
    350}
    351
    352/*
    353 *  sii164IsConnected
    354 *      Check if the DVI Monitor is connected.
    355 *
    356 *  Output:
    357 *      0   - Not Connected
    358 *      1   - Connected
    359 */
    360unsigned char sii164IsConnected(void)
    361{
    362	unsigned char hotPlugValue;
    363
    364	hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
    365		       SII164_DETECT_HOT_PLUG_STATUS_MASK;
    366	if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
    367		return 1;
    368	else
    369		return 0;
    370}
    371
    372/*
    373 *  sii164CheckInterrupt
    374 *      Checks if interrupt has occurred.
    375 *
    376 *  Output:
    377 *      0   - No interrupt
    378 *      1   - Interrupt occurs
    379 */
    380unsigned char sii164CheckInterrupt(void)
    381{
    382	unsigned char detectReg;
    383
    384	detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) &
    385		    SII164_DETECT_MONITOR_STATE_MASK;
    386	if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
    387		return 1;
    388	else
    389		return 0;
    390}
    391
    392/*
    393 *  sii164ClearInterrupt
    394 *      Clear the hot plug interrupt.
    395 */
    396void sii164ClearInterrupt(void)
    397{
    398	unsigned char detectReg;
    399
    400	/* Clear the MDI interrupt */
    401	detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
    402	i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT,
    403		    detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
    404}
    405
    406#endif
    407
    408#endif