Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 1 | #include "ddk750_reg.h" |
| 2 | #include "ddk750_help.h" |
| 3 | #include "ddk750_display.h" |
| 4 | #include "ddk750_power.h" |
| 5 | #include "ddk750_dvi.h" |
| 6 | |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 7 | #define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 8 | |
Amitoj Kaur Chawla | edb2302 | 2015-10-10 02:17:44 +0530 | [diff] [blame] | 9 | static void setDisplayControl(int ctrl, int disp_state) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 10 | { |
| 11 | /* state != 0 means turn on both timing & plane en_bit */ |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 12 | unsigned long reg, val, reserved; |
| 13 | int cnt = 0; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 14 | |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 15 | if (!ctrl) { |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 16 | reg = PANEL_DISPLAY_CTRL; |
| 17 | reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK; |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 18 | } else { |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 19 | reg = CRT_DISPLAY_CTRL; |
| 20 | reserved = CRT_DISPLAY_CTRL_RESERVED_MASK; |
| 21 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 22 | |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 23 | val = PEEK32(reg); |
| 24 | if (disp_state) { |
| 25 | /* |
| 26 | * Timing should be enabled first before enabling the |
| 27 | * plane because changing at the same time does not |
| 28 | * guarantee that the plane will also enabled or |
| 29 | * disabled. |
| 30 | */ |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 31 | val |= DISPLAY_CTRL_TIMING; |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 32 | POKE32(reg, val); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 33 | |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 34 | val |= DISPLAY_CTRL_PLANE; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 35 | |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 36 | /* |
| 37 | * Somehow the register value on the plane is not set |
| 38 | * until a few delay. Need to write and read it a |
| 39 | * couple times |
| 40 | */ |
| 41 | do { |
| 42 | cnt++; |
| 43 | POKE32(reg, val); |
| 44 | } while ((PEEK32(reg) & ~reserved) != (val & ~reserved)); |
| 45 | pr_debug("Set Plane enbit:after tried %d times\n", cnt); |
| 46 | } else { |
| 47 | /* |
| 48 | * When turning off, there is no rule on the |
| 49 | * programming sequence since whenever the clock is |
| 50 | * off, then it does not matter whether the plane is |
| 51 | * enabled or disabled. Note: Modifying the plane bit |
| 52 | * will take effect on the next vertical sync. Need to |
| 53 | * find out if it is necessary to wait for 1 vsync |
| 54 | * before modifying the timing enable bit. |
| 55 | */ |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 56 | val &= ~DISPLAY_CTRL_PLANE; |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 57 | POKE32(reg, val); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 58 | |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 59 | val &= ~DISPLAY_CTRL_TIMING; |
Mike Rapoport | b117b63 | 2016-02-10 18:34:06 +0200 | [diff] [blame] | 60 | POKE32(reg, val); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 61 | } |
| 62 | } |
| 63 | |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 64 | static void waitNextVerticalSync(int ctrl, int delay) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 65 | { |
| 66 | unsigned int status; |
Juston Li | 40403c1 | 2015-07-14 21:14:48 -0700 | [diff] [blame] | 67 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 68 | if (!ctrl) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 69 | /* primary controller */ |
| 70 | |
yeongjun Kim | c9d67dc | 2016-06-15 00:36:07 +0900 | [diff] [blame] | 71 | /* |
| 72 | * Do not wait when the Primary PLL is off or display control is |
| 73 | * already off. This will prevent the software to wait forever. |
| 74 | */ |
Mike Rapoport | 5557eb1 | 2016-02-10 18:33:57 +0200 | [diff] [blame] | 75 | if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) || |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 76 | !(PEEK32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 77 | return; |
| 78 | } |
| 79 | |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 80 | while (delay-- > 0) { |
Juston Li | 7837653 | 2015-07-14 21:14:30 -0700 | [diff] [blame] | 81 | /* Wait for end of vsync. */ |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 82 | do { |
Mike Rapoport | 410c756 | 2016-01-17 20:04:18 +0200 | [diff] [blame] | 83 | status = PEEK32(SYSTEM_CTRL); |
| 84 | } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 85 | |
Juston Li | 7837653 | 2015-07-14 21:14:30 -0700 | [diff] [blame] | 86 | /* Wait for start of vsync. */ |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 87 | do { |
Mike Rapoport | 410c756 | 2016-01-17 20:04:18 +0200 | [diff] [blame] | 88 | status = PEEK32(SYSTEM_CTRL); |
| 89 | } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE)); |
Juston Li | 7837653 | 2015-07-14 21:14:30 -0700 | [diff] [blame] | 90 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 91 | |
Juston Li | 6338a781 | 2015-07-14 21:14:36 -0700 | [diff] [blame] | 92 | } else { |
yeongjun Kim | c9d67dc | 2016-06-15 00:36:07 +0900 | [diff] [blame] | 93 | /* |
| 94 | * Do not wait when the Primary PLL is off or display control is |
| 95 | * already off. This will prevent the software to wait forever. |
| 96 | */ |
Mike Rapoport | 5557eb1 | 2016-02-10 18:33:57 +0200 | [diff] [blame] | 97 | if (!(PEEK32(CRT_PLL_CTRL) & PLL_CTRL_POWER) || |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 98 | !(PEEK32(CRT_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 99 | return; |
| 100 | } |
| 101 | |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 102 | while (delay-- > 0) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 103 | /* Wait for end of vsync. */ |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 104 | do { |
Mike Rapoport | 410c756 | 2016-01-17 20:04:18 +0200 | [diff] [blame] | 105 | status = PEEK32(SYSTEM_CTRL); |
| 106 | } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 107 | |
| 108 | /* Wait for start of vsync. */ |
Juston Li | 259fef3 | 2015-07-14 21:14:45 -0700 | [diff] [blame] | 109 | do { |
Mike Rapoport | 410c756 | 2016-01-17 20:04:18 +0200 | [diff] [blame] | 110 | status = PEEK32(SYSTEM_CTRL); |
| 111 | } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE)); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 112 | } |
| 113 | } |
| 114 | } |
| 115 | |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 116 | static void swPanelPowerSequence(int disp, int delay) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 117 | { |
| 118 | unsigned int reg; |
| 119 | |
| 120 | /* disp should be 1 to open sequence */ |
| 121 | reg = PEEK32(PANEL_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 122 | reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0); |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 123 | POKE32(PANEL_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 124 | primaryWaitVerticalSync(delay); |
| 125 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 126 | reg = PEEK32(PANEL_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 127 | reg |= (disp ? PANEL_DISPLAY_CTRL_DATA : 0); |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 128 | POKE32(PANEL_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 129 | primaryWaitVerticalSync(delay); |
| 130 | |
| 131 | reg = PEEK32(PANEL_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 132 | reg |= (disp ? PANEL_DISPLAY_CTRL_VBIASEN : 0); |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 133 | POKE32(PANEL_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 134 | primaryWaitVerticalSync(delay); |
| 135 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 136 | reg = PEEK32(PANEL_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 137 | reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0); |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 138 | POKE32(PANEL_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 139 | primaryWaitVerticalSync(delay); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | void ddk750_setLogicalDispOut(disp_output_t output) |
| 143 | { |
| 144 | unsigned int reg; |
Juston Li | 40403c1 | 2015-07-14 21:14:48 -0700 | [diff] [blame] | 145 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 146 | if (output & PNL_2_USAGE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 147 | /* set panel path controller select */ |
| 148 | reg = PEEK32(PANEL_DISPLAY_CTRL); |
Mike Rapoport | c4e893b | 2016-02-10 18:34:10 +0200 | [diff] [blame] | 149 | reg &= ~PANEL_DISPLAY_CTRL_SELECT_MASK; |
| 150 | reg |= (((output & PNL_2_MASK) >> PNL_2_OFFSET) << |
| 151 | PANEL_DISPLAY_CTRL_SELECT_SHIFT); |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 152 | POKE32(PANEL_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 153 | } |
| 154 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 155 | if (output & CRT_2_USAGE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 156 | /* set crt path controller select */ |
| 157 | reg = PEEK32(CRT_DISPLAY_CTRL); |
Mike Rapoport | cdce1f1 | 2016-02-10 18:34:19 +0200 | [diff] [blame] | 158 | reg &= ~CRT_DISPLAY_CTRL_SELECT_MASK; |
| 159 | reg |= (((output & CRT_2_MASK) >> CRT_2_OFFSET) << |
| 160 | CRT_DISPLAY_CTRL_SELECT_SHIFT); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 161 | /*se blank off */ |
Mike Rapoport | d8264ed | 2016-02-10 18:34:18 +0200 | [diff] [blame] | 162 | reg &= ~CRT_DISPLAY_CTRL_BLANK; |
Isaac Assegai | da29504 | 2015-06-02 03:14:30 -0700 | [diff] [blame] | 163 | POKE32(CRT_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 164 | } |
| 165 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 166 | if (output & PRI_TP_USAGE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 167 | /* set primary timing and plane en_bit */ |
Amitoj Kaur Chawla | aeec43d | 2015-10-10 02:21:30 +0530 | [diff] [blame] | 168 | setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 169 | } |
| 170 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 171 | if (output & SEC_TP_USAGE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 172 | /* set secondary timing and plane en_bit*/ |
Amitoj Kaur Chawla | aeec43d | 2015-10-10 02:21:30 +0530 | [diff] [blame] | 173 | setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 174 | } |
| 175 | |
Juston Li | 8c11f5a | 2015-07-14 21:14:35 -0700 | [diff] [blame] | 176 | if (output & PNL_SEQ_USAGE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 177 | /* set panel sequence */ |
Amitoj Kaur Chawla | aeec43d | 2015-10-10 02:21:30 +0530 | [diff] [blame] | 178 | swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 179 | } |
| 180 | |
Juston Li | 9ccc5f4 | 2015-07-14 21:14:33 -0700 | [diff] [blame] | 181 | if (output & DAC_USAGE) |
Amitoj Kaur Chawla | e80ef45 | 2015-10-10 02:20:36 +0530 | [diff] [blame] | 182 | setDAC((output & DAC_MASK) >> DAC_OFFSET); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 183 | |
Juston Li | 9ccc5f4 | 2015-07-14 21:14:33 -0700 | [diff] [blame] | 184 | if (output & DPMS_USAGE) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 185 | ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET); |
| 186 | } |