aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index b6a03447ea63..a0dc41e27733 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -151,7 +151,7 @@ static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */
151 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 151 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
152} 152}
153 153
154static inline u8 ipc_data_readl(u32 offset) /* Read ipc u32 data */ 154static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */
155{ 155{
156 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 156 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
157} 157}
@@ -181,18 +181,19 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
181 int nc; 181 int nc;
182 u32 offset = 0; 182 u32 offset = 0;
183 u32 err = 0; 183 u32 err = 0;
184 u8 cbuf[IPC_WWBUF_SIZE] = { '\0' }; 184 u8 cbuf[IPC_WWBUF_SIZE] = { };
185 u32 *wbuf = (u32 *)&cbuf; 185 u32 *wbuf = (u32 *)&cbuf;
186 186
187 mutex_lock(&ipclock); 187 mutex_lock(&ipclock);
188
188 if (ipcdev.pdev == NULL) { 189 if (ipcdev.pdev == NULL) {
189 mutex_unlock(&ipclock); 190 mutex_unlock(&ipclock);
190 return -ENODEV; 191 return -ENODEV;
191 } 192 }
192 193
193 if (platform == 1) { 194 if (platform == PLATFORM_LANGWELL) {
194 /* Entry is 4 bytes for read/write, 5 bytes for read modify */ 195 /* Entry is 4 bytes for read/write, 5 bytes for read modify */
195 for (nc = 0; nc < count; nc++) { 196 for (nc = 0; nc < count; nc++, offset += 3) {
196 cbuf[offset] = addr[nc]; 197 cbuf[offset] = addr[nc];
197 cbuf[offset + 1] = addr[nc] >> 8; 198 cbuf[offset + 1] = addr[nc] >> 8;
198 if (id != IPC_CMD_PCNTRL_R) 199 if (id != IPC_CMD_PCNTRL_R)
@@ -201,33 +202,44 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
201 cbuf[offset + 3] = data[nc + 1]; 202 cbuf[offset + 3] = data[nc + 1];
202 offset += 1; 203 offset += 1;
203 } 204 }
204 offset += 3;
205 } 205 }
206 for (nc = 0, offset = 0; nc < count; nc++, offset += 4) 206 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
207 ipc_data_writel(wbuf[nc], offset); /* Write wbuff */ 207 ipc_data_writel(wbuf[nc], offset); /* Write wbuff */
208 208
209 if (id != IPC_CMD_PCNTRL_M)
210 ipc_command((count*4) << 16 | id << 12 | 0 << 8 | op);
211 else
212 ipc_command((count*5) << 16 | id << 12 | 0 << 8 | op);
213
209 } else { 214 } else {
210 for (nc = 0, offset = 0; nc < count; nc++, offset += 2) 215 for (nc = 0; nc < count; nc++, offset += 2) {
211 ipc_data_writel(addr[nc], offset); /* Write addresses */ 216 cbuf[offset] = addr[nc];
212 if (id != IPC_CMD_PCNTRL_R) { 217 cbuf[offset + 1] = addr[nc] >> 8;
213 for (nc = 0; nc < count; nc++, offset++)
214 ipc_data_writel(data[nc], offset); /* Write data */
215 if (id == IPC_CMD_PCNTRL_M)
216 ipc_data_writel(data[nc + 1], offset); /* Mask value*/
217 } 218 }
218 }
219 219
220 if (id != IPC_CMD_PCNTRL_M) 220 if (id == IPC_CMD_PCNTRL_R) {
221 ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); 221 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
222 else 222 ipc_data_writel(wbuf[nc], offset);
223 ipc_command((count * 4) << 16 | id << 12 | 0 << 8 | op); 223 ipc_command((count*2) << 16 | id << 12 | 0 << 8 | op);
224 } else if (id == IPC_CMD_PCNTRL_W) {
225 for (nc = 0; nc < count; nc++, offset += 1)
226 cbuf[offset] = data[nc];
227 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
228 ipc_data_writel(wbuf[nc], offset);
229 ipc_command((count*3) << 16 | id << 12 | 0 << 8 | op);
230 } else if (id == IPC_CMD_PCNTRL_M) {
231 cbuf[offset] = data[0];
232 cbuf[offset + 1] = data[1];
233 ipc_data_writel(wbuf[0], 0); /* Write wbuff */
234 ipc_command(4 << 16 | id << 12 | 0 << 8 | op);
235 }
236 }
224 237
225 err = busy_loop(); 238 err = busy_loop();
226
227 if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ 239 if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
228 /* Workaround: values are read as 0 without memcpy_fromio */ 240 /* Workaround: values are read as 0 without memcpy_fromio */
229 memcpy_fromio(cbuf, ipcdev.ipc_base + IPC_READ_BUFFER, 16); 241 memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16);
230 if (platform == 1) { 242 if (platform == PLATFORM_LANGWELL) {
231 for (nc = 0, offset = 2; nc < count; nc++, offset += 3) 243 for (nc = 0, offset = 2; nc < count; nc++, offset += 3)
232 data[nc] = ipc_data_readb(offset); 244 data[nc] = ipc_data_readb(offset);
233 } else { 245 } else {
@@ -800,6 +812,7 @@ static void ipc_remove(struct pci_dev *pdev)
800 812
801static const struct pci_device_id pci_ids[] = { 813static const struct pci_device_id pci_ids[] = {
802 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)}, 814 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)},
815 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)},
803 { 0,} 816 { 0,}
804}; 817};
805MODULE_DEVICE_TABLE(pci, pci_ids); 818MODULE_DEVICE_TABLE(pci, pci_ids);