root/drivers/staging/sm750fb/ddk750_mode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. displayControlAdjust_SM750LE
  2. programModeRegisters
  3. ddk750_setModeTiming

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

/* [<][>][^][v][top][bottom][index][help] */