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_mode.c (6877B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#include "ddk750_reg.h"
      4#include "ddk750_mode.h"
      5#include "ddk750_chip.h"
      6
      7/*
      8 * SM750LE only:
      9 * This function takes care extra registers and bit fields required to set
     10 * up a mode in SM750LE
     11 *
     12 * Explanation about Display Control register:
     13 * HW only supports 7 predefined pixel clocks, and clock select is
     14 * in bit 29:27 of Display Control register.
     15 */
     16static unsigned long
     17displayControlAdjust_SM750LE(struct mode_parameter *pModeParam,
     18			     unsigned long dispControl)
     19{
     20	unsigned long x, y;
     21
     22	x = pModeParam->horizontal_display_end;
     23	y = pModeParam->vertical_display_end;
     24
     25	/*
     26	 * SM750LE has to set up the top-left and bottom-right
     27	 * registers as well.
     28	 * Note that normal SM750/SM718 only use those two register for
     29	 * auto-centering mode.
     30	 */
     31	poke32(CRT_AUTO_CENTERING_TL, 0);
     32
     33	poke32(CRT_AUTO_CENTERING_BR,
     34	       (((y - 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT) &
     35		CRT_AUTO_CENTERING_BR_BOTTOM_MASK) |
     36	       ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK));
     37
     38	/*
     39	 * Assume common fields in dispControl have been properly set before
     40	 * calling this function.
     41	 * This function only sets the extra fields in dispControl.
     42	 */
     43
     44	/* Clear bit 29:27 of display control register */
     45	dispControl &= ~CRT_DISPLAY_CTRL_CLK_MASK;
     46
     47	/* Set bit 29:27 of display control register for the right clock */
     48	/* Note that SM750LE only need to supported 7 resolutions. */
     49	if (x == 800 && y == 600)
     50		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL41;
     51	else if (x == 1024 && y == 768)
     52		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL65;
     53	else if (x == 1152 && y == 864)
     54		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
     55	else if (x == 1280 && y == 768)
     56		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
     57	else if (x == 1280 && y == 720)
     58		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL74;
     59	else if (x == 1280 && y == 960)
     60		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
     61	else if (x == 1280 && y == 1024)
     62		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
     63	else /* default to VGA clock */
     64		dispControl |= CRT_DISPLAY_CTRL_CLK_PLL25;
     65
     66	/* Set bit 25:24 of display controller */
     67	dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
     68
     69	/* Set bit 14 of display controller */
     70	dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
     71
     72	poke32(CRT_DISPLAY_CTRL, dispControl);
     73
     74	return dispControl;
     75}
     76
     77/* only timing related registers will be  programed */
     78static int programModeRegisters(struct mode_parameter *pModeParam,
     79				struct pll_value *pll)
     80{
     81	int ret = 0;
     82	int cnt = 0;
     83	unsigned int tmp, reg;
     84
     85	if (pll->clock_type == SECONDARY_PLL) {
     86		/* programe secondary pixel clock */
     87		poke32(CRT_PLL_CTRL, sm750_format_pll_reg(pll));
     88
     89		tmp = ((pModeParam->horizontal_total - 1) <<
     90		       CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
     91		     CRT_HORIZONTAL_TOTAL_TOTAL_MASK;
     92		tmp |= (pModeParam->horizontal_display_end - 1) &
     93		      CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK;
     94
     95		poke32(CRT_HORIZONTAL_TOTAL, tmp);
     96
     97		tmp = (pModeParam->horizontal_sync_width <<
     98		       CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) &
     99		     CRT_HORIZONTAL_SYNC_WIDTH_MASK;
    100		tmp |= (pModeParam->horizontal_sync_start - 1) &
    101		      CRT_HORIZONTAL_SYNC_START_MASK;
    102
    103		poke32(CRT_HORIZONTAL_SYNC, tmp);
    104
    105		tmp = ((pModeParam->vertical_total - 1) <<
    106		       CRT_VERTICAL_TOTAL_TOTAL_SHIFT) &
    107		     CRT_VERTICAL_TOTAL_TOTAL_MASK;
    108		tmp |= (pModeParam->vertical_display_end - 1) &
    109		      CRT_VERTICAL_TOTAL_DISPLAY_END_MASK;
    110
    111		poke32(CRT_VERTICAL_TOTAL, tmp);
    112
    113		tmp = ((pModeParam->vertical_sync_height <<
    114		       CRT_VERTICAL_SYNC_HEIGHT_SHIFT)) &
    115		     CRT_VERTICAL_SYNC_HEIGHT_MASK;
    116		tmp |= (pModeParam->vertical_sync_start - 1) &
    117		      CRT_VERTICAL_SYNC_START_MASK;
    118
    119		poke32(CRT_VERTICAL_SYNC, tmp);
    120
    121		tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
    122		if (pModeParam->vertical_sync_polarity)
    123			tmp |= DISPLAY_CTRL_VSYNC_PHASE;
    124		if (pModeParam->horizontal_sync_polarity)
    125			tmp |= DISPLAY_CTRL_HSYNC_PHASE;
    126
    127		if (sm750_get_chip_type() == SM750LE) {
    128			displayControlAdjust_SM750LE(pModeParam, tmp);
    129		} else {
    130			reg = peek32(CRT_DISPLAY_CTRL) &
    131				~(DISPLAY_CTRL_VSYNC_PHASE |
    132				  DISPLAY_CTRL_HSYNC_PHASE |
    133				  DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE);
    134
    135			poke32(CRT_DISPLAY_CTRL, tmp | reg);
    136		}
    137
    138	} else if (pll->clock_type == PRIMARY_PLL) {
    139		unsigned int reserved;
    140
    141		poke32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll));
    142
    143		reg = ((pModeParam->horizontal_total - 1) <<
    144			PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
    145			PANEL_HORIZONTAL_TOTAL_TOTAL_MASK;
    146		reg |= ((pModeParam->horizontal_display_end - 1) &
    147			PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK);
    148		poke32(PANEL_HORIZONTAL_TOTAL, reg);
    149
    150		poke32(PANEL_HORIZONTAL_SYNC,
    151		       ((pModeParam->horizontal_sync_width <<
    152			 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) &
    153			PANEL_HORIZONTAL_SYNC_WIDTH_MASK) |
    154		       ((pModeParam->horizontal_sync_start - 1) &
    155			PANEL_HORIZONTAL_SYNC_START_MASK));
    156
    157		poke32(PANEL_VERTICAL_TOTAL,
    158		       (((pModeParam->vertical_total - 1) <<
    159			 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) &
    160			PANEL_VERTICAL_TOTAL_TOTAL_MASK) |
    161		       ((pModeParam->vertical_display_end - 1) &
    162			PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK));
    163
    164		poke32(PANEL_VERTICAL_SYNC,
    165		       ((pModeParam->vertical_sync_height <<
    166			 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) &
    167			PANEL_VERTICAL_SYNC_HEIGHT_MASK) |
    168		       ((pModeParam->vertical_sync_start - 1) &
    169			PANEL_VERTICAL_SYNC_START_MASK));
    170
    171		tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
    172		if (pModeParam->vertical_sync_polarity)
    173			tmp |= DISPLAY_CTRL_VSYNC_PHASE;
    174		if (pModeParam->horizontal_sync_polarity)
    175			tmp |= DISPLAY_CTRL_HSYNC_PHASE;
    176		if (pModeParam->clock_phase_polarity)
    177			tmp |= DISPLAY_CTRL_CLOCK_PHASE;
    178
    179		reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK |
    180			PANEL_DISPLAY_CTRL_VSYNC;
    181
    182		reg = (peek32(PANEL_DISPLAY_CTRL) & ~reserved) &
    183			~(DISPLAY_CTRL_CLOCK_PHASE | DISPLAY_CTRL_VSYNC_PHASE |
    184			  DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING |
    185			  DISPLAY_CTRL_PLANE);
    186
    187		/*
    188		 * May a hardware bug or just my test chip (not confirmed).
    189		 * PANEL_DISPLAY_CTRL register seems requiring few writes
    190		 * before a value can be successfully written in.
    191		 * Added some masks to mask out the reserved bits.
    192		 * Note: This problem happens by design. The hardware will wait
    193		 *       for the next vertical sync to turn on/off the plane.
    194		 */
    195		poke32(PANEL_DISPLAY_CTRL, tmp | reg);
    196
    197		while ((peek32(PANEL_DISPLAY_CTRL) & ~reserved) !=
    198			(tmp | reg)) {
    199			cnt++;
    200			if (cnt > 1000)
    201				break;
    202			poke32(PANEL_DISPLAY_CTRL, tmp | reg);
    203		}
    204	} else {
    205		ret = -1;
    206	}
    207	return ret;
    208}
    209
    210int ddk750_setModeTiming(struct mode_parameter *parm, enum clock_type clock)
    211{
    212	struct pll_value pll;
    213
    214	pll.input_freq = DEFAULT_INPUT_CLOCK;
    215	pll.clock_type = clock;
    216
    217	sm750_calc_pll_value(parm->pixel_clock, &pll);
    218	if (sm750_get_chip_type() == SM750LE) {
    219		/* set graphic mode via IO method */
    220		outb_p(0x88, 0x3d4);
    221		outb_p(0x06, 0x3d5);
    222	}
    223	programModeRegisters(parm, &pll);
    224	return 0;
    225}