Mike Rapoport | e074da3 | 2016-02-19 17:56:13 +0200 | [diff] [blame] | 1 | #include <linux/kernel.h> |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 2 | #include <linux/sizes.h> |
| 3 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 4 | #include "ddk750_help.h" |
| 5 | #include "ddk750_reg.h" |
| 6 | #include "ddk750_chip.h" |
| 7 | #include "ddk750_power.h" |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 8 | |
Mike Rapoport | 603dd49 | 2016-02-19 17:56:14 +0200 | [diff] [blame] | 9 | #define MHz(x) ((x) * 1000000) |
| 10 | |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 11 | logical_chip_type_t sm750_get_chip_type(void) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 12 | { |
| 13 | unsigned short physicalID; |
| 14 | char physicalRev; |
| 15 | logical_chip_type_t chip; |
| 16 | |
Juston Li | 5ee35ea | 2015-06-12 03:17:22 -0700 | [diff] [blame] | 17 | physicalID = devId750; /* either 0x718 or 0x750 */ |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 18 | physicalRev = revId750; |
| 19 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 20 | if (physicalID == 0x718) |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 21 | chip = SM718; |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 22 | else if (physicalID == 0x750) { |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 23 | chip = SM750; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 24 | /* SM750 and SM750LE are different in their revision ID only. */ |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 25 | if (physicalRev == SM750LE_REVISION_ID) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 26 | chip = SM750LE; |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 27 | } else |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 28 | chip = SM_UNKNOWN; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 29 | |
| 30 | return chip; |
| 31 | } |
| 32 | |
Mike Rapoport | 7092d76 | 2015-10-13 09:26:45 +0300 | [diff] [blame] | 33 | static unsigned int get_mxclk_freq(void) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 34 | { |
Mike Rapoport | 7751e0e | 2015-10-13 09:26:44 +0300 | [diff] [blame] | 35 | unsigned int pll_reg; |
| 36 | unsigned int M, N, OD, POD; |
| 37 | |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 38 | if (sm750_get_chip_type() == SM750LE) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 39 | return MHz(130); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 40 | |
Mike Rapoport | 7751e0e | 2015-10-13 09:26:44 +0300 | [diff] [blame] | 41 | pll_reg = PEEK32(MXCLK_PLL_CTRL); |
Mike Rapoport | cdd5df6 | 2016-02-10 18:33:58 +0200 | [diff] [blame] | 42 | M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT; |
| 43 | N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT; |
| 44 | OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT; |
| 45 | POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT; |
Mike Rapoport | 7751e0e | 2015-10-13 09:26:44 +0300 | [diff] [blame] | 46 | |
| 47 | return DEFAULT_INPUT_CLOCK * M / N / (1 << OD) / (1 << POD); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 48 | } |
| 49 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 50 | /* |
| 51 | * This function set up the main chip clock. |
| 52 | * |
| 53 | * Input: Frequency to be set. |
| 54 | */ |
Mike Rapoport | fb6f37a | 2015-09-30 08:24:54 +0300 | [diff] [blame] | 55 | static void setChipClock(unsigned int frequency) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 56 | { |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 57 | pll_value_t pll; |
| 58 | unsigned int ulActualMxClk; |
Mike Rapoport | cfac7d6 | 2015-10-22 09:38:39 +0300 | [diff] [blame] | 59 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 60 | /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 61 | if (sm750_get_chip_type() == SM750LE) |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 62 | return; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 63 | |
Amitoj Kaur Chawla | 59f0840 | 2015-04-02 23:01:04 +0530 | [diff] [blame] | 64 | if (frequency) { |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 65 | /* |
| 66 | * Set up PLL, a structure to hold the value to be set in clocks. |
| 67 | */ |
| 68 | pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ |
| 69 | pll.clockType = MXCLK_PLL; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 70 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 71 | /* |
Moshe Green | 46b7dd7 | 2016-09-15 23:15:50 +0300 | [diff] [blame] | 72 | * Call calcPllValue() to fill the other fields of PLL structure. |
| 73 | * Sometime, the chip cannot set up the exact clock |
| 74 | * required by the User. |
| 75 | * Return value of calcPllValue gives the actual possible clock. |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 76 | */ |
| 77 | ulActualMxClk = calcPllValue(frequency, &pll); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 78 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 79 | /* Master Clock Control: MXCLK_PLL */ |
| 80 | POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); |
| 81 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 82 | } |
| 83 | |
Mike Rapoport | fb6f37a | 2015-09-30 08:24:54 +0300 | [diff] [blame] | 84 | static void setMemoryClock(unsigned int frequency) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 85 | { |
Mike Rapoport | 19aa211 | 2016-01-17 20:04:26 +0200 | [diff] [blame] | 86 | unsigned int reg, divisor; |
Mike Rapoport | cfac7d6 | 2015-10-22 09:38:39 +0300 | [diff] [blame] | 87 | |
Moshe Green | f90416d | 2016-06-05 22:09:24 +0300 | [diff] [blame] | 88 | /* Cheok_0509: For SM750LE, the memory clock is fixed. |
| 89 | * Nothing to set. |
| 90 | */ |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 91 | if (sm750_get_chip_type() == SM750LE) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 92 | return; |
Mike Rapoport | cfac7d6 | 2015-10-22 09:38:39 +0300 | [diff] [blame] | 93 | |
Amitoj Kaur Chawla | 59f0840 | 2015-04-02 23:01:04 +0530 | [diff] [blame] | 94 | if (frequency) { |
Moshe Green | d943005 | 2016-06-06 22:04:32 +0300 | [diff] [blame] | 95 | /* |
Moshe Green | 46b7dd7 | 2016-09-15 23:15:50 +0300 | [diff] [blame] | 96 | * Set the frequency to the maximum frequency |
| 97 | * that the DDR Memory can take which is 336MHz. |
Moshe Green | d943005 | 2016-06-06 22:04:32 +0300 | [diff] [blame] | 98 | */ |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 99 | if (frequency > MHz(336)) |
| 100 | frequency = MHz(336); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 101 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 102 | /* Calculate the divisor */ |
Moshe Green | 42f8f21 | 2016-10-02 14:04:46 +0300 | [diff] [blame] | 103 | divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 104 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 105 | /* Set the corresponding divisor in the register. */ |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 106 | reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK; |
Helen Fornazier | c107243 | 2015-03-26 14:09:17 -0300 | [diff] [blame] | 107 | switch (divisor) { |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 108 | default: |
| 109 | case 1: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 110 | reg |= CURRENT_GATE_M2XCLK_DIV_1; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 111 | break; |
| 112 | case 2: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 113 | reg |= CURRENT_GATE_M2XCLK_DIV_2; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 114 | break; |
| 115 | case 3: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 116 | reg |= CURRENT_GATE_M2XCLK_DIV_3; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 117 | break; |
| 118 | case 4: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 119 | reg |= CURRENT_GATE_M2XCLK_DIV_4; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 120 | break; |
| 121 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 122 | |
Mike Rapoport | 19aa211 | 2016-01-17 20:04:26 +0200 | [diff] [blame] | 123 | setCurrentGate(reg); |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 124 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 125 | } |
| 126 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 127 | /* |
| 128 | * This function set up the master clock (MCLK). |
| 129 | * |
| 130 | * Input: Frequency to be set. |
| 131 | * |
| 132 | * NOTE: |
| 133 | * The maximum frequency the engine can run is 168MHz. |
| 134 | */ |
Mike Rapoport | fb6f37a | 2015-09-30 08:24:54 +0300 | [diff] [blame] | 135 | static void setMasterClock(unsigned int frequency) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 136 | { |
Mike Rapoport | 19aa211 | 2016-01-17 20:04:26 +0200 | [diff] [blame] | 137 | unsigned int reg, divisor; |
Mike Rapoport | cfac7d6 | 2015-10-22 09:38:39 +0300 | [diff] [blame] | 138 | |
Moshe Green | 83d6283 | 2016-06-01 23:34:21 +0300 | [diff] [blame] | 139 | /* Cheok_0509: For SM750LE, the memory clock is fixed. |
| 140 | * Nothing to set. |
| 141 | */ |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 142 | if (sm750_get_chip_type() == SM750LE) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 143 | return; |
Mike Rapoport | cfac7d6 | 2015-10-22 09:38:39 +0300 | [diff] [blame] | 144 | |
Amitoj Kaur Chawla | 59f0840 | 2015-04-02 23:01:04 +0530 | [diff] [blame] | 145 | if (frequency) { |
Moshe Green | b29376c3 | 2016-09-15 23:16:11 +0300 | [diff] [blame] | 146 | /* Set the frequency to the maximum frequency |
| 147 | * that the SM750 engine can run, which is about 190 MHz. |
| 148 | */ |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 149 | if (frequency > MHz(190)) |
| 150 | frequency = MHz(190); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 151 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 152 | /* Calculate the divisor */ |
Moshe Green | 42f8f21 | 2016-10-02 14:04:46 +0300 | [diff] [blame] | 153 | divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 154 | |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 155 | /* Set the corresponding divisor in the register. */ |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 156 | reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK; |
Helen Fornazier | c107243 | 2015-03-26 14:09:17 -0300 | [diff] [blame] | 157 | switch (divisor) { |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 158 | default: |
| 159 | case 3: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 160 | reg |= CURRENT_GATE_MCLK_DIV_3; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 161 | break; |
| 162 | case 4: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 163 | reg |= CURRENT_GATE_MCLK_DIV_4; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 164 | break; |
| 165 | case 6: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 166 | reg |= CURRENT_GATE_MCLK_DIV_6; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 167 | break; |
| 168 | case 8: |
Mike Rapoport | 6e8aa4a | 2016-01-17 20:04:27 +0200 | [diff] [blame] | 169 | reg |= CURRENT_GATE_MCLK_DIV_8; |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 170 | break; |
| 171 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 172 | |
Mike Rapoport | 19aa211 | 2016-01-17 20:04:26 +0200 | [diff] [blame] | 173 | setCurrentGate(reg); |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 174 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 175 | } |
| 176 | |
Supriya Karanth | 6fa7db8 | 2015-03-12 01:11:00 +0900 | [diff] [blame] | 177 | unsigned int ddk750_getVMSize(void) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 178 | { |
| 179 | unsigned int reg; |
| 180 | unsigned int data; |
| 181 | |
| 182 | /* sm750le only use 64 mb memory*/ |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 183 | if (sm750_get_chip_type() == SM750LE) |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 184 | return SZ_64M; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 185 | |
| 186 | /* for 750,always use power mode0*/ |
| 187 | reg = PEEK32(MODE0_GATE); |
Mike Rapoport | 05e9d9e | 2016-01-17 20:04:28 +0200 | [diff] [blame] | 188 | reg |= MODE0_GATE_GPIO; |
Helen Fornazier | c04051f | 2015-03-26 14:09:18 -0300 | [diff] [blame] | 189 | POKE32(MODE0_GATE, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 190 | |
| 191 | /* get frame buffer size from GPIO */ |
Mike Rapoport | 5538d5c | 2016-01-17 20:04:24 +0200 | [diff] [blame] | 192 | reg = PEEK32(MISC_CTRL) & MISC_CTRL_LOCALMEM_SIZE_MASK; |
Helen Fornazier | c107243 | 2015-03-26 14:09:17 -0300 | [diff] [blame] | 193 | switch (reg) { |
Helen Fornazier | ae59c46 | 2015-03-26 14:09:19 -0300 | [diff] [blame] | 194 | case MISC_CTRL_LOCALMEM_SIZE_8M: |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 195 | data = SZ_8M; break; /* 8 Mega byte */ |
Helen Fornazier | ae59c46 | 2015-03-26 14:09:19 -0300 | [diff] [blame] | 196 | case MISC_CTRL_LOCALMEM_SIZE_16M: |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 197 | data = SZ_16M; break; /* 16 Mega byte */ |
Helen Fornazier | ae59c46 | 2015-03-26 14:09:19 -0300 | [diff] [blame] | 198 | case MISC_CTRL_LOCALMEM_SIZE_32M: |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 199 | data = SZ_32M; break; /* 32 Mega byte */ |
Helen Fornazier | ae59c46 | 2015-03-26 14:09:19 -0300 | [diff] [blame] | 200 | case MISC_CTRL_LOCALMEM_SIZE_64M: |
Mike Rapoport | 4cf26d8 | 2015-09-22 12:01:17 +0300 | [diff] [blame] | 201 | data = SZ_64M; break; /* 64 Mega byte */ |
Helen Fornazier | ae59c46 | 2015-03-26 14:09:19 -0300 | [diff] [blame] | 202 | default: |
Amitoj Kaur Chawla | e261e69 | 2015-04-02 22:57:55 +0530 | [diff] [blame] | 203 | data = 0; |
| 204 | break; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 205 | } |
| 206 | return data; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 207 | } |
| 208 | |
Helen Fornazier | f8da055 | 2015-03-26 14:09:20 -0300 | [diff] [blame] | 209 | int ddk750_initHw(initchip_param_t *pInitParam) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 210 | { |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 211 | unsigned int reg; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 212 | |
Juston Li | 8332d94 | 2015-07-14 21:14:32 -0700 | [diff] [blame] | 213 | if (pInitParam->powerMode != 0) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 214 | pInitParam->powerMode = 0; |
| 215 | setPowerMode(pInitParam->powerMode); |
| 216 | |
| 217 | /* Enable display power gate & LOCALMEM power gate*/ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 218 | reg = PEEK32(CURRENT_GATE); |
Mike Rapoport | 90946e5 | 2016-01-17 20:04:25 +0200 | [diff] [blame] | 219 | reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM); |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 220 | setCurrentGate(reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 221 | |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 222 | if (sm750_get_chip_type() != SM750LE) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 223 | /* set panel pll and graphic mode via mmio_88 */ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 224 | reg = PEEK32(VGA_CONFIGURATION); |
Mike Rapoport | d979814 | 2016-02-10 18:34:00 +0200 | [diff] [blame] | 225 | reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE); |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 226 | POKE32(VGA_CONFIGURATION, reg); |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 227 | } else { |
Amitoj Kaur Chawla | 31296ba | 2015-04-08 22:25:06 +0530 | [diff] [blame] | 228 | #if defined(__i386__) || defined(__x86_64__) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 229 | /* set graphic mode via IO method */ |
Helen Fornazier | c04051f | 2015-03-26 14:09:18 -0300 | [diff] [blame] | 230 | outb_p(0x88, 0x3d4); |
| 231 | outb_p(0x06, 0x3d5); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 232 | #endif |
| 233 | } |
| 234 | |
| 235 | /* Set the Main Chip Clock */ |
| 236 | setChipClock(MHz((unsigned int)pInitParam->chipClock)); |
| 237 | |
| 238 | /* Set up memory clock. */ |
| 239 | setMemoryClock(MHz(pInitParam->memClock)); |
| 240 | |
| 241 | /* Set up master clock */ |
| 242 | setMasterClock(MHz(pInitParam->masterClock)); |
| 243 | |
| 244 | |
Moshe Green | b29376c3 | 2016-09-15 23:16:11 +0300 | [diff] [blame] | 245 | /* Reset the memory controller. |
| 246 | * If the memory controller is not reset in SM750, |
| 247 | * the system might hang when sw accesses the memory. |
| 248 | * The memory should be resetted after changing the MXCLK. |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 249 | */ |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 250 | if (pInitParam->resetMemory == 1) { |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 251 | reg = PEEK32(MISC_CTRL); |
Mike Rapoport | 5372350 | 2016-01-17 20:04:21 +0200 | [diff] [blame] | 252 | reg &= ~MISC_CTRL_LOCALMEM_RESET; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 253 | POKE32(MISC_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 254 | |
Mike Rapoport | 5372350 | 2016-01-17 20:04:21 +0200 | [diff] [blame] | 255 | reg |= MISC_CTRL_LOCALMEM_RESET; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 256 | POKE32(MISC_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 257 | } |
| 258 | |
Helen Fornazier | 9767fc5 | 2015-03-26 14:09:14 -0300 | [diff] [blame] | 259 | if (pInitParam->setAllEngOff == 1) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 260 | enable2DEngine(0); |
| 261 | |
| 262 | /* Disable Overlay, if a former application left it on */ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 263 | reg = PEEK32(VIDEO_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 264 | reg &= ~DISPLAY_CTRL_PLANE; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 265 | POKE32(VIDEO_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 266 | |
| 267 | /* Disable video alpha, if a former application left it on */ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 268 | reg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 269 | reg &= ~DISPLAY_CTRL_PLANE; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 270 | POKE32(VIDEO_ALPHA_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 271 | |
| 272 | /* Disable alpha plane, if a former application left it on */ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 273 | reg = PEEK32(ALPHA_DISPLAY_CTRL); |
Mike Rapoport | 6fba39c | 2016-02-10 18:34:08 +0200 | [diff] [blame] | 274 | reg &= ~DISPLAY_CTRL_PLANE; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 275 | POKE32(ALPHA_DISPLAY_CTRL, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 276 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 277 | /* Disable DMA Channel, if a former application left it on */ |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 278 | reg = PEEK32(DMA_ABORT_INTERRUPT); |
Mike Rapoport | 0f23be7 | 2016-02-10 18:34:17 +0200 | [diff] [blame] | 279 | reg |= DMA_ABORT_INTERRUPT_ABORT_1; |
Mike Rapoport | 8bc728c | 2016-01-17 20:04:20 +0200 | [diff] [blame] | 280 | POKE32(DMA_ABORT_INTERRUPT, reg); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 281 | |
| 282 | /* Disable DMA Power, if a former application left it on */ |
| 283 | enableDMA(0); |
| 284 | } |
| 285 | |
| 286 | /* We can add more initialization as needed. */ |
| 287 | |
| 288 | return 0; |
| 289 | } |
| 290 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 291 | /* |
Moshe Green | b29376c3 | 2016-09-15 23:16:11 +0300 | [diff] [blame] | 292 | * monk liu @ 4/6/2011: |
| 293 | * re-write the calculatePLL function of ddk750. |
| 294 | * the original version function does not use |
| 295 | * some mathematics tricks and shortcut |
| 296 | * when it doing the calculation of the best N,M,D combination |
| 297 | * I think this version gives a little upgrade in speed |
| 298 | * |
| 299 | * 750 pll clock formular: |
| 300 | * Request Clock = (Input Clock * M )/(N * X) |
| 301 | * |
| 302 | * Input Clock = 14318181 hz |
| 303 | * X = 2 power D |
| 304 | * D ={0,1,2,3,4,5,6} |
| 305 | * M = {1,...,255} |
| 306 | * N = {2,...,15} |
| 307 | */ |
Helen Fornazier | c04051f | 2015-03-26 14:09:18 -0300 | [diff] [blame] | 308 | unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll) |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 309 | { |
Moshe Green | 46b7dd7 | 2016-09-15 23:15:50 +0300 | [diff] [blame] | 310 | /* as sm750 register definition, |
| 311 | * N located in 2,15 and M located in 1,255 |
| 312 | */ |
Helen Fornazier | c04051f | 2015-03-26 14:09:18 -0300 | [diff] [blame] | 313 | int N, M, X, d; |
Amitoj Kaur Chawla | 43ce0b5 | 2015-10-10 02:14:27 +0530 | [diff] [blame] | 314 | int mini_diff; |
Helen Fornazier | c04051f | 2015-03-26 14:09:18 -0300 | [diff] [blame] | 315 | unsigned int RN, quo, rem, fl_quo; |
| 316 | unsigned int input, request; |
| 317 | unsigned int tmpClock, ret; |
Mike Rapoport | a61dc13 | 2015-10-22 09:38:40 +0300 | [diff] [blame] | 318 | const int max_OD = 3; |
Colin Ian King | f0e00da | 2016-03-29 17:53:23 +0100 | [diff] [blame] | 319 | int max_d = 6; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 320 | |
Moshe Green | 06a4f42 | 2016-09-25 22:58:35 +0300 | [diff] [blame] | 321 | if (sm750_get_chip_type() == SM750LE) { |
Moshe Green | b29376c3 | 2016-09-15 23:16:11 +0300 | [diff] [blame] | 322 | /* SM750LE don't have |
| 323 | * programmable PLL and M/N values to work on. |
| 324 | * Just return the requested clock. |
| 325 | */ |
Ragavendra Nagraj | de99bef | 2015-03-18 02:37:42 -0700 | [diff] [blame] | 326 | return request_orig; |
| 327 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 328 | |
| 329 | ret = 0; |
Amitoj Kaur Chawla | 43ce0b5 | 2015-10-10 02:14:27 +0530 | [diff] [blame] | 330 | mini_diff = ~0; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 331 | request = request_orig / 1000; |
| 332 | input = pll->inputFreq / 1000; |
| 333 | |
Moshe Green | 46b7dd7 | 2016-09-15 23:15:50 +0300 | [diff] [blame] | 334 | /* for MXCLK register, |
| 335 | * no POD provided, so need be treated differently |
| 336 | */ |
Mike Rapoport | a61dc13 | 2015-10-22 09:38:40 +0300 | [diff] [blame] | 337 | if (pll->clockType == MXCLK_PLL) |
| 338 | max_d = 3; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 339 | |
Helen Fornazier | ce02a16a | 2015-03-26 14:09:15 -0300 | [diff] [blame] | 340 | for (N = 15; N > 1; N--) { |
Moshe Green | 46b7dd7 | 2016-09-15 23:15:50 +0300 | [diff] [blame] | 341 | /* RN will not exceed maximum long |
| 342 | * if @request <= 285 MHZ (for 32bit cpu) |
| 343 | */ |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 344 | RN = N * request; |
| 345 | quo = RN / input; |
| 346 | rem = RN % input;/* rem always small than 14318181 */ |
Juston Li | 6ab5b6d | 2015-07-14 21:14:40 -0700 | [diff] [blame] | 347 | fl_quo = (rem * 10000 / input); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 348 | |
Mike Rapoport | a61dc13 | 2015-10-22 09:38:40 +0300 | [diff] [blame] | 349 | for (d = max_d; d >= 0; d--) { |
Rehas Sachdeva | f3151e0 | 2016-09-20 17:36:29 +0530 | [diff] [blame] | 350 | X = BIT(d); |
Amitoj Kaur Chawla | f40917e | 2015-10-04 20:12:30 +0530 | [diff] [blame] | 351 | M = quo * X; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 352 | M += fl_quo * X / 10000; |
| 353 | /* round step */ |
Amitoj Kaur Chawla | 07387cb | 2015-10-04 20:18:32 +0530 | [diff] [blame] | 354 | M += (fl_quo * X % 10000) > 5000 ? 1 : 0; |
Helen Fornazier | 82736d2 | 2015-03-26 14:09:16 -0300 | [diff] [blame] | 355 | if (M < 256 && M > 0) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 356 | unsigned int diff; |
Juston Li | 40403c1 | 2015-07-14 21:14:48 -0700 | [diff] [blame] | 357 | |
Juston Li | 6ab5b6d | 2015-07-14 21:14:40 -0700 | [diff] [blame] | 358 | tmpClock = pll->inputFreq * M / N / X; |
Mike Rapoport | e074da3 | 2016-02-19 17:56:13 +0200 | [diff] [blame] | 359 | diff = abs(tmpClock - request_orig); |
Amitoj Kaur Chawla | 43ce0b5 | 2015-10-10 02:14:27 +0530 | [diff] [blame] | 360 | if (diff < mini_diff) { |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 361 | pll->M = M; |
| 362 | pll->N = N; |
Mike Rapoport | a61dc13 | 2015-10-22 09:38:40 +0300 | [diff] [blame] | 363 | pll->POD = 0; |
| 364 | if (d > max_OD) |
| 365 | pll->POD = d - max_OD; |
| 366 | pll->OD = d - pll->POD; |
Amitoj Kaur Chawla | 43ce0b5 | 2015-10-10 02:14:27 +0530 | [diff] [blame] | 367 | mini_diff = diff; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 368 | ret = tmpClock; |
| 369 | } |
| 370 | } |
| 371 | } |
| 372 | } |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 373 | return ret; |
| 374 | } |
| 375 | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 376 | unsigned int formatPllReg(pll_value_t *pPLL) |
| 377 | { |
Mike Rapoport | cdd5df6 | 2016-02-10 18:33:58 +0200 | [diff] [blame] | 378 | #ifndef VALIDATION_CHIP |
| 379 | unsigned int POD = pPLL->POD; |
| 380 | #endif |
| 381 | unsigned int OD = pPLL->OD; |
| 382 | unsigned int M = pPLL->M; |
| 383 | unsigned int N = pPLL->N; |
Mike Rapoport | 375b4d4 | 2016-02-10 18:33:53 +0200 | [diff] [blame] | 384 | unsigned int reg = 0; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 385 | |
Mike Rapoport | 0c4d85f | 2016-02-10 18:33:54 +0200 | [diff] [blame] | 386 | /* |
| 387 | * Note that all PLL's have the same format. Here, we just use |
| 388 | * Panel PLL parameter to work out the bit fields in the |
| 389 | * register. On returning a 32 bit number, the value can be |
| 390 | * applied to any PLL in the calling function. |
| 391 | */ |
Mike Rapoport | cdd5df6 | 2016-02-10 18:33:58 +0200 | [diff] [blame] | 392 | reg = PLL_CTRL_POWER | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 393 | #ifndef VALIDATION_CHIP |
Mike Rapoport | cdd5df6 | 2016-02-10 18:33:58 +0200 | [diff] [blame] | 394 | ((POD << PLL_CTRL_POD_SHIFT) & PLL_CTRL_POD_MASK) | |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 395 | #endif |
Mike Rapoport | cdd5df6 | 2016-02-10 18:33:58 +0200 | [diff] [blame] | 396 | ((OD << PLL_CTRL_OD_SHIFT) & PLL_CTRL_OD_MASK) | |
| 397 | ((N << PLL_CTRL_N_SHIFT) & PLL_CTRL_N_MASK) | |
| 398 | ((M << PLL_CTRL_M_SHIFT) & PLL_CTRL_M_MASK); |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 399 | |
Mike Rapoport | 375b4d4 | 2016-02-10 18:33:53 +0200 | [diff] [blame] | 400 | return reg; |
Sudip Mukherjee | 81dee67 | 2015-03-03 16:21:06 +0530 | [diff] [blame] | 401 | } |
| 402 | |
| 403 | |