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