Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /*
3 : * Copyright (C) 2013--2024 Intel Corporation
4 : */
5 :
6 : #include <linux/bitfield.h>
7 : #include <linux/bits.h>
8 : #include <linux/completion.h>
9 : #include <linux/delay.h>
10 : #include <linux/device.h>
11 : #include <linux/dma-mapping.h>
12 : #include <linux/firmware.h>
13 : #include <linux/interrupt.h>
14 : #include <linux/iopoll.h>
15 : #include <linux/math64.h>
16 : #include <linux/mm.h>
17 : #include <linux/mutex.h>
18 : #include <linux/pci.h>
19 : #include <linux/pfn.h>
20 : #include <linux/pm_runtime.h>
21 : #include <linux/scatterlist.h>
22 : #include <linux/slab.h>
23 : #include <linux/time64.h>
24 :
25 : #include "ipu6.h"
26 : #include "ipu6-bus.h"
27 : #include "ipu6-dma.h"
28 : #include "ipu6-buttress.h"
29 : #include "ipu6-platform-buttress-regs.h"
30 :
31 : #include "ipu4-compat.h"
32 :
33 : #define IPU4_BOOTLOADER_STATUS_OFFSET 0x8000
34 : #define IPU6_BOOTLOADER_STATUS_OFFSET 0x15c
35 :
36 : #define BOOTLOADER_MAGIC_KEY 0xb00710ad
37 :
38 : #define ENTRY BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1
39 : #define EXIT BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2
40 : #define QUERY BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE
41 :
42 : #define IPU4_BUTTRESS_TSC_CLOCK_FREQUENCY 192
43 : #define BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX 10
44 :
45 : #define BUTTRESS_POWER_TIMEOUT_US (200 * USEC_PER_MSEC)
46 :
47 : #define BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US (5 * USEC_PER_SEC)
48 : #define BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US (10 * USEC_PER_SEC)
49 : #define BUTTRESS_CSE_FWRESET_TIMEOUT_US (100 * USEC_PER_MSEC)
50 :
51 : #define BUTTRESS_IPC_TX_TIMEOUT_MS MSEC_PER_SEC
52 : #define BUTTRESS_IPC_RX_TIMEOUT_MS MSEC_PER_SEC
53 : #define BUTTRESS_IPC_VALIDITY_TIMEOUT_US (1 * USEC_PER_SEC)
54 : #define BUTTRESS_TSC_SYNC_TIMEOUT_US (5 * USEC_PER_MSEC)
55 :
56 : #define BUTTRESS_IPC_RESET_RETRY 2000
57 : #define BUTTRESS_CSE_IPC_RESET_RETRY 4
58 : #define BUTTRESS_IPC_CMD_SEND_RETRY 1
59 :
60 : #define BUTTRESS_MAX_CONSECUTIVE_IRQS 100
61 :
62 : static const u32 ipu6_adev_irq_mask[2] = {
63 : BUTTRESS_ISR_IS_IRQ,
64 : BUTTRESS_ISR_PS_IRQ
65 : };
66 :
67 1 : int ipu6_buttress_ipc_reset(struct ipu6_device *isp,
68 : struct ipu6_buttress_ipc *ipc)
69 : {
70 : unsigned int retries = BUTTRESS_IPC_RESET_RETRY;
71 : struct ipu6_buttress *b = &isp->buttress;
72 : u32 val = 0, csr_in_clr;
73 :
74 1 : if (!isp->secure_mode) {
75 0 : dev_dbg(&isp->pdev->dev, "Skip IPC reset for non-secure mode");
76 0 : return 0;
77 : }
78 :
79 1 : mutex_lock(&b->ipc_mutex);
80 :
81 : /* Clear-by-1 CSR (all bits), corresponding internal states. */
82 1 : val = readl(isp->base + ipc->csr_in);
83 1 : writel(val, isp->base + ipc->csr_in);
84 :
85 : /* Set peer CSR bit IPC_PEER_COMP_ACTIONS_RST_PHASE1 */
86 1 : writel(ENTRY, isp->base + ipc->csr_out);
87 : /*
88 : * Clear-by-1 all CSR bits EXCEPT following
89 : * bits:
90 : * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
91 : * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
92 : * C. Possibly custom bits, depending on
93 : * their role.
94 : */
95 : csr_in_clr = BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ |
96 : BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID |
97 : BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ | QUERY;
98 :
99 : do {
100 : usleep_range(400, 500);
101 1 : val = readl(isp->base + ipc->csr_in);
102 1 : switch (val) {
103 0 : case ENTRY | EXIT:
104 : case ENTRY | EXIT | QUERY:
105 : /*
106 : * 1) Clear-by-1 CSR bits
107 : * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
108 : * IPC_PEER_COMP_ACTIONS_RST_PHASE2).
109 : * 2) Set peer CSR bit
110 : * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
111 : */
112 0 : writel(ENTRY | EXIT, isp->base + ipc->csr_in);
113 0 : writel(QUERY, isp->base + ipc->csr_out);
114 : break;
115 0 : case ENTRY:
116 : case ENTRY | QUERY:
117 : /*
118 : * 1) Clear-by-1 CSR bits
119 : * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
120 : * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE).
121 : * 2) Set peer CSR bit
122 : * IPC_PEER_COMP_ACTIONS_RST_PHASE1.
123 : */
124 0 : writel(ENTRY | QUERY, isp->base + ipc->csr_in);
125 0 : writel(ENTRY, isp->base + ipc->csr_out);
126 : break;
127 1 : case EXIT:
128 : case EXIT | QUERY:
129 : /*
130 : * Clear-by-1 CSR bit
131 : * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
132 : * 1) Clear incoming doorbell.
133 : * 2) Clear-by-1 all CSR bits EXCEPT following
134 : * bits:
135 : * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
136 : * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
137 : * C. Possibly custom bits, depending on
138 : * their role.
139 : * 3) Set peer CSR bit
140 : * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
141 : */
142 1 : writel(EXIT, isp->base + ipc->csr_in);
143 1 : writel(0, isp->base + ipc->db0_in);
144 1 : writel(csr_in_clr, isp->base + ipc->csr_in);
145 1 : writel(EXIT, isp->base + ipc->csr_out);
146 :
147 : /*
148 : * Read csr_in again to make sure if RST_PHASE2 is done.
149 : * If csr_in is QUERY, it should be handled again.
150 : */
151 : usleep_range(200, 300);
152 1 : val = readl(isp->base + ipc->csr_in);
153 1 : if (val & QUERY) {
154 0 : dev_dbg(&isp->pdev->dev,
155 : "RST_PHASE2 retry csr_in = %x\n", val);
156 : break;
157 : }
158 1 : mutex_unlock(&b->ipc_mutex);
159 1 : return 0;
160 0 : case QUERY:
161 : /*
162 : * 1) Clear-by-1 CSR bit
163 : * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
164 : * 2) Set peer CSR bit
165 : * IPC_PEER_COMP_ACTIONS_RST_PHASE1
166 : */
167 0 : writel(QUERY, isp->base + ipc->csr_in);
168 0 : writel(ENTRY, isp->base + ipc->csr_out);
169 : break;
170 : default:
171 0 : dev_dbg_ratelimited(&isp->pdev->dev,
172 : "Unexpected CSR 0x%x\n", val);
173 : break;
174 : }
175 0 : } while (retries--);
176 :
177 0 : mutex_unlock(&b->ipc_mutex);
178 0 : dev_err(&isp->pdev->dev, "Timed out while waiting for CSE\n");
179 :
180 0 : return -ETIMEDOUT;
181 : }
182 :
183 : static void ipu6_buttress_ipc_validity_close(struct ipu6_device *isp,
184 : struct ipu6_buttress_ipc *ipc)
185 : {
186 : writel(BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ,
187 0 : isp->base + ipc->csr_out);
188 0 : }
189 :
190 : static int
191 0 : ipu6_buttress_ipc_validity_open(struct ipu6_device *isp,
192 : struct ipu6_buttress_ipc *ipc)
193 : {
194 : unsigned int mask = BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID;
195 : void __iomem *addr;
196 : int ret;
197 : u32 val;
198 :
199 : writel(BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ,
200 0 : isp->base + ipc->csr_out);
201 :
202 0 : addr = isp->base + ipc->csr_in;
203 0 : ret = readl_poll_timeout(addr, val, val & mask, 200,
204 : BUTTRESS_IPC_VALIDITY_TIMEOUT_US);
205 : if (ret) {
206 0 : dev_err(&isp->pdev->dev, "CSE validity timeout 0x%x\n", val);
207 : ipu6_buttress_ipc_validity_close(isp, ipc);
208 : }
209 :
210 0 : return ret;
211 : }
212 :
213 : static void ipu6_buttress_ipc_recv(struct ipu6_device *isp,
214 : struct ipu6_buttress_ipc *ipc, u32 *ipc_msg)
215 : {
216 0 : if (ipc_msg)
217 0 : *ipc_msg = readl(isp->base + ipc->data0_in);
218 0 : writel(0, isp->base + ipc->db0_in);
219 : }
220 :
221 0 : static int ipu6_buttress_ipc_send_bulk(struct ipu6_device *isp,
222 : struct ipu6_ipc_buttress_bulk_msg *msgs,
223 : u32 size)
224 : {
225 : unsigned long tx_timeout_jiffies, rx_timeout_jiffies;
226 : unsigned int i, retry = BUTTRESS_IPC_CMD_SEND_RETRY;
227 : struct ipu6_buttress *b = &isp->buttress;
228 0 : struct ipu6_buttress_ipc *ipc = &b->cse;
229 : u32 val;
230 : int ret;
231 : int tout;
232 :
233 0 : mutex_lock(&b->ipc_mutex);
234 :
235 0 : ret = ipu6_buttress_ipc_validity_open(isp, ipc);
236 0 : if (ret) {
237 0 : dev_err(&isp->pdev->dev, "IPC validity open failed\n");
238 0 : goto out;
239 : }
240 :
241 : tx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_TX_TIMEOUT_MS);
242 : rx_timeout_jiffies = msecs_to_jiffies(BUTTRESS_IPC_RX_TIMEOUT_MS);
243 :
244 0 : for (i = 0; i < size; i++) {
245 : reinit_completion(&ipc->send_complete);
246 0 : if (msgs[i].require_resp)
247 : reinit_completion(&ipc->recv_complete);
248 :
249 0 : dev_dbg(&isp->pdev->dev, "bulk IPC command: 0x%x\n",
250 : msgs[i].cmd);
251 0 : writel(msgs[i].cmd, isp->base + ipc->data0_out);
252 0 : val = BUTTRESS_IU2CSEDB0_BUSY | msgs[i].cmd_size;
253 0 : writel(val, isp->base + ipc->db0_out);
254 :
255 0 : tout = wait_for_completion_timeout(&ipc->send_complete,
256 : tx_timeout_jiffies);
257 0 : if (!tout) {
258 0 : dev_err(&isp->pdev->dev, "send IPC response timeout\n");
259 0 : if (!retry--) {
260 : ret = -ETIMEDOUT;
261 0 : goto out;
262 : }
263 :
264 : /* Try again if CSE is not responding on first try */
265 0 : writel(0, isp->base + ipc->db0_out);
266 0 : i--;
267 0 : continue;
268 : }
269 :
270 : retry = BUTTRESS_IPC_CMD_SEND_RETRY;
271 :
272 0 : if (!msgs[i].require_resp)
273 0 : continue;
274 :
275 0 : tout = wait_for_completion_timeout(&ipc->recv_complete,
276 : rx_timeout_jiffies);
277 0 : if (!tout) {
278 0 : dev_err(&isp->pdev->dev, "recv IPC response timeout\n");
279 : ret = -ETIMEDOUT;
280 0 : goto out;
281 : }
282 :
283 0 : if (ipc->nack_mask &&
284 0 : (ipc->recv_data & ipc->nack_mask) == ipc->nack) {
285 0 : dev_err(&isp->pdev->dev,
286 : "IPC NACK for cmd 0x%x\n", msgs[i].cmd);
287 : ret = -EIO;
288 0 : goto out;
289 : }
290 :
291 0 : if (ipc->recv_data != msgs[i].expected_resp) {
292 0 : dev_err(&isp->pdev->dev,
293 : "expected resp: 0x%x, IPC response: 0x%x ",
294 : msgs[i].expected_resp, ipc->recv_data);
295 : ret = -EIO;
296 0 : goto out;
297 : }
298 : }
299 :
300 0 : dev_dbg(&isp->pdev->dev, "bulk IPC commands done\n");
301 :
302 0 : out:
303 : ipu6_buttress_ipc_validity_close(isp, ipc);
304 0 : mutex_unlock(&b->ipc_mutex);
305 0 : return ret;
306 : }
307 :
308 : static int
309 : ipu6_buttress_ipc_send(struct ipu6_device *isp,
310 : u32 ipc_msg, u32 size, bool require_resp,
311 : u32 expected_resp)
312 : {
313 0 : struct ipu6_ipc_buttress_bulk_msg msg = {
314 : .cmd = ipc_msg,
315 : .cmd_size = size,
316 : .require_resp = require_resp,
317 : .expected_resp = expected_resp,
318 : };
319 :
320 0 : return ipu6_buttress_ipc_send_bulk(isp, &msg, 1);
321 : }
322 :
323 10 : static irqreturn_t ipu6_buttress_call_isr(struct ipu6_bus_device *adev)
324 : {
325 : irqreturn_t ret = IRQ_WAKE_THREAD;
326 :
327 10 : if (!adev || !adev->auxdrv || !adev->auxdrv_data)
328 : return IRQ_NONE;
329 :
330 5 : if (adev->auxdrv_data->isr)
331 5 : ret = adev->auxdrv_data->isr(adev);
332 :
333 5 : if (ret == IRQ_WAKE_THREAD && !adev->auxdrv_data->isr_threaded)
334 : ret = IRQ_NONE;
335 :
336 : return ret;
337 : }
338 :
339 5 : irqreturn_t ipu6_buttress_isr(int irq, void *isp_ptr)
340 : {
341 : struct ipu6_device *isp = isp_ptr;
342 5 : struct ipu6_bus_device *adev[] = { isp->isys, isp->psys };
343 : struct ipu6_buttress *b = &isp->buttress;
344 : irqreturn_t ret = IRQ_NONE;
345 : u32 disable_irqs = 0;
346 : u32 irq_status;
347 : u32 i, count = 0;
348 : int active;
349 :
350 5 : active = pm_runtime_get_if_active(&isp->pdev->dev);
351 5 : if (!active)
352 : return IRQ_NONE;
353 :
354 5 : irq_status = readl(isp->base + b->reg_irq_sts);
355 5 : if (irq_status == 0 || WARN_ON_ONCE(irq_status == 0xffffffffu)) {
356 0 : if (active > 0)
357 0 : pm_runtime_put_noidle(&isp->pdev->dev);
358 0 : return IRQ_NONE;
359 : }
360 :
361 : do {
362 5 : writel(irq_status, isp->base + BUTTRESS_REG_ISR_CLEAR);
363 :
364 15 : for (i = 0; i < ARRAY_SIZE(ipu6_adev_irq_mask); i++) {
365 10 : irqreturn_t r = ipu6_buttress_call_isr(adev[i]);
366 :
367 10 : if (!(irq_status & ipu6_adev_irq_mask[i]))
368 5 : continue;
369 :
370 5 : if (r == IRQ_WAKE_THREAD) {
371 : ret = IRQ_WAKE_THREAD;
372 0 : disable_irqs |= ipu6_adev_irq_mask[i];
373 5 : } else if (ret == IRQ_NONE && r == IRQ_HANDLED) {
374 : ret = IRQ_HANDLED;
375 : }
376 : }
377 :
378 5 : if ((irq_status & BUTTRESS_EVENT) && ret == IRQ_NONE)
379 : ret = IRQ_HANDLED;
380 :
381 5 : if (irq_status & BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING) {
382 0 : dev_dbg(&isp->pdev->dev,
383 : "BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING\n");
384 0 : ipu6_buttress_ipc_recv(isp, &b->cse, &b->cse.recv_data);
385 0 : complete(&b->cse.recv_complete);
386 : }
387 :
388 5 : if (irq_status & BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE) {
389 0 : dev_dbg(&isp->pdev->dev,
390 : "BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE\n");
391 0 : complete(&b->cse.send_complete);
392 : }
393 :
394 5 : if (irq_status & BUTTRESS_ISR_SAI_VIOLATION &&
395 : ipu6_buttress_get_secure_mode(isp))
396 0 : dev_err(&isp->pdev->dev,
397 : "BUTTRESS_ISR_SAI_VIOLATION\n");
398 :
399 5 : if (irq_status & (BUTTRESS_ISR_IS_FATAL_MEM_ERR |
400 : BUTTRESS_ISR_PS_FATAL_MEM_ERR))
401 0 : dev_err(&isp->pdev->dev,
402 : "BUTTRESS_ISR_FATAL_MEM_ERR\n");
403 :
404 5 : if (irq_status & BUTTRESS_ISR_UFI_ERROR)
405 0 : dev_err(&isp->pdev->dev, "BUTTRESS_ISR_UFI_ERROR\n");
406 :
407 5 : if (++count == BUTTRESS_MAX_CONSECUTIVE_IRQS) {
408 0 : dev_err(&isp->pdev->dev, "too many consecutive IRQs\n");
409 : ret = IRQ_NONE;
410 0 : break;
411 : }
412 :
413 5 : irq_status = readl(isp->base + b->reg_irq_sts);
414 5 : } while (irq_status);
415 :
416 5 : if (disable_irqs)
417 0 : writel(BUTTRESS_IRQS & ~disable_irqs,
418 0 : isp->base + BUTTRESS_REG_ISR_ENABLE);
419 :
420 5 : if (active > 0)
421 5 : pm_runtime_put(&isp->pdev->dev);
422 :
423 : return ret;
424 : }
425 :
426 0 : irqreturn_t ipu6_buttress_isr_threaded(int irq, void *isp_ptr)
427 : {
428 : struct ipu6_device *isp = isp_ptr;
429 0 : struct ipu6_bus_device *adev[] = { isp->isys, isp->psys };
430 : const struct ipu6_auxdrv_data *drv_data = NULL;
431 : irqreturn_t ret = IRQ_NONE;
432 : unsigned int i;
433 :
434 0 : for (i = 0; i < ARRAY_SIZE(ipu6_adev_irq_mask) && adev[i]; i++) {
435 0 : drv_data = adev[i]->auxdrv_data;
436 0 : if (!drv_data)
437 0 : continue;
438 :
439 0 : if (drv_data->wake_isr_thread &&
440 0 : drv_data->isr_threaded(adev[i]) == IRQ_HANDLED)
441 : ret = IRQ_HANDLED;
442 : }
443 :
444 0 : writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE);
445 :
446 0 : return ret;
447 : }
448 :
449 8 : int ipu6_buttress_power(struct device *dev,
450 : const struct ipu6_buttress_ctrl *ctrl, bool on)
451 : {
452 8 : struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp;
453 : u32 pwr_sts, val;
454 : int ret;
455 :
456 8 : if (!ctrl)
457 : return 0;
458 :
459 8 : mutex_lock(&isp->buttress.power_mutex);
460 :
461 8 : if (!on) {
462 : val = 0;
463 4 : pwr_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
464 : } else {
465 4 : val = BUTTRESS_FREQ_CTL_START |
466 4 : FIELD_PREP(BUTTRESS_FREQ_CTL_RATIO_MASK,
467 4 : ctrl->ratio) |
468 4 : FIELD_PREP(BUTTRESS_FREQ_CTL_QOS_FLOOR_MASK,
469 : ctrl->qos_floor) |
470 : IPU4_BUTTRESS_FREQ_CTL_ICCMAX_LEVEL;
471 :
472 4 : pwr_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
473 : }
474 :
475 8 : writel(val, isp->base + ctrl->freq_ctl);
476 :
477 16 : ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATE,
478 : val, (val & ctrl->pwr_sts_mask) == pwr_sts,
479 : 100, BUTTRESS_POWER_TIMEOUT_US);
480 : if (ret)
481 0 : dev_err(&isp->pdev->dev,
482 : "Change power status timeout with 0x%x\n", val);
483 :
484 8 : mutex_unlock(&isp->buttress.power_mutex);
485 :
486 8 : return ret;
487 : }
488 :
489 0 : bool ipu6_buttress_get_secure_mode(struct ipu6_device *isp)
490 : {
491 : u32 val;
492 :
493 0 : val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
494 :
495 1 : return val & BUTTRESS_SECURITY_CTL_FW_SECURE_MODE;
496 : }
497 :
498 0 : bool ipu6_buttress_auth_done(struct ipu6_device *isp)
499 : {
500 : u32 val;
501 :
502 2 : if (!isp->secure_mode)
503 : return true;
504 :
505 2 : val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
506 : val = FIELD_GET(BUTTRESS_SECURITY_CTL_FW_SETUP_MASK, val);
507 :
508 0 : return val == BUTTRESS_SECURITY_CTL_AUTH_DONE;
509 : }
510 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_auth_done, INTEL_IPU6);
511 :
512 0 : int ipu6_buttress_reset_authentication(struct ipu6_device *isp)
513 : {
514 : int ret;
515 : u32 val;
516 :
517 0 : if (!isp->secure_mode) {
518 0 : dev_dbg(&isp->pdev->dev, "Skip auth for non-secure mode\n");
519 0 : return 0;
520 : }
521 :
522 0 : writel(BUTTRESS_FW_RESET_CTL_START, isp->base +
523 : BUTTRESS_REG_FW_RESET_CTL);
524 :
525 0 : ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val,
526 : val & BUTTRESS_FW_RESET_CTL_DONE, 500,
527 : BUTTRESS_CSE_FWRESET_TIMEOUT_US);
528 : if (ret) {
529 0 : dev_err(&isp->pdev->dev,
530 : "Time out while resetting authentication state\n");
531 0 : return ret;
532 : }
533 :
534 0 : dev_dbg(&isp->pdev->dev, "FW reset for authentication done\n");
535 0 : writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL);
536 : /* leave some time for HW restore */
537 : usleep_range(800, 1000);
538 :
539 0 : return 0;
540 : }
541 :
542 1 : int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys,
543 : const struct firmware *fw, struct sg_table *sgt)
544 : {
545 1 : bool is_vmalloc = is_vmalloc_addr(fw->data);
546 1 : struct pci_dev *pdev = sys->isp->pdev;
547 : struct page **pages;
548 : const void *addr;
549 : unsigned long n_pages;
550 : unsigned int i;
551 : int ret;
552 :
553 1 : if (!is_vmalloc && !virt_addr_valid(fw->data))
554 : return -EDOM;
555 :
556 1 : n_pages = PFN_UP(fw->size);
557 :
558 1 : pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
559 1 : if (!pages)
560 : return -ENOMEM;
561 :
562 1 : addr = fw->data;
563 2 : for (i = 0; i < n_pages; i++) {
564 : struct page *p = is_vmalloc ?
565 1 : vmalloc_to_page(addr) : virt_to_page(addr);
566 :
567 1 : if (!p) {
568 : ret = -ENOMEM;
569 0 : goto out;
570 : }
571 1 : pages[i] = p;
572 1 : addr += PAGE_SIZE;
573 : }
574 :
575 1 : ret = sg_alloc_table_from_pages(sgt, pages, n_pages, 0, fw->size,
576 : GFP_KERNEL);
577 1 : if (ret) {
578 : ret = -ENOMEM;
579 0 : goto out;
580 : }
581 :
582 1 : ret = dma_map_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
583 1 : if (ret) {
584 0 : sg_free_table(sgt);
585 0 : goto out;
586 : }
587 :
588 1 : ret = ipu6_dma_map_sgtable(sys, sgt, DMA_TO_DEVICE, 0);
589 1 : if (ret) {
590 : dma_unmap_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
591 0 : sg_free_table(sgt);
592 0 : goto out;
593 : }
594 :
595 1 : ipu6_dma_sync_sgtable(sys, sgt);
596 :
597 1 : out:
598 1 : kfree(pages);
599 :
600 1 : return ret;
601 : }
602 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_map_fw_image, INTEL_IPU6);
603 :
604 0 : void ipu6_buttress_unmap_fw_image(struct ipu6_bus_device *sys,
605 : struct sg_table *sgt)
606 : {
607 0 : struct pci_dev *pdev = sys->isp->pdev;
608 :
609 0 : ipu6_dma_unmap_sgtable(sys, sgt, DMA_TO_DEVICE, 0);
610 0 : dma_unmap_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
611 0 : sg_free_table(sgt);
612 0 : }
613 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_unmap_fw_image, INTEL_IPU6);
614 :
615 2 : int ipu6_buttress_authenticate(struct ipu6_device *isp)
616 : {
617 : struct ipu6_buttress *b = &isp->buttress;
618 : struct ipu6_psys_pdata *psys_pdata;
619 : u32 data, mask, done, fail;
620 : int ret;
621 2 : u32 bootloader_status_offset = is_ipu4(isp->hw_ver) ?
622 2 : IPU4_BOOTLOADER_STATUS_OFFSET : IPU6_BOOTLOADER_STATUS_OFFSET;
623 :
624 2 : if (!isp->secure_mode) {
625 0 : dev_dbg(&isp->pdev->dev, "Skip auth for non-secure mode\n");
626 0 : return 0;
627 : }
628 :
629 2 : psys_pdata = isp->psys->pdata;
630 :
631 2 : mutex_lock(&b->auth_mutex);
632 :
633 2 : ret = pm_runtime_resume_and_get(&isp->pdev->dev);
634 2 : if (ret < 0)
635 0 : goto out_unlock;
636 :
637 2 : if (ipu6_buttress_auth_done(isp)) {
638 : ret = 0;
639 2 : goto out_pm_put;
640 : }
641 :
642 : /*
643 : * Write address of FIT table to FW_SOURCE register
644 : * Let's use fw address. I.e. not using FIT table yet
645 : */
646 0 : data = lower_32_bits(isp->psys->pkg_dir_dma_addr);
647 0 : writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_LO);
648 :
649 0 : data = upper_32_bits(isp->psys->pkg_dir_dma_addr);
650 0 : writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_HI);
651 :
652 : /*
653 : * Write boot_load into IU2CSEDATA0
654 : * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
655 : * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
656 : */
657 0 : dev_info(&isp->pdev->dev, "Sending BOOT_LOAD to CSE\n");
658 :
659 : ret = ipu6_buttress_ipc_send(isp,
660 : BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD,
661 : 1, true,
662 : BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE);
663 0 : if (ret) {
664 0 : dev_err(&isp->pdev->dev, "CSE boot_load failed\n");
665 0 : goto out_pm_put;
666 : }
667 :
668 : mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK;
669 : done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE;
670 : fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED;
671 0 : ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
672 : ((data & mask) == done ||
673 : (data & mask) == fail), 500,
674 : BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
675 : if (ret) {
676 0 : dev_err(&isp->pdev->dev, "CSE boot_load timeout\n");
677 0 : goto out_pm_put;
678 : }
679 :
680 0 : if ((data & mask) == fail) {
681 0 : dev_err(&isp->pdev->dev, "CSE auth failed\n");
682 : ret = -EINVAL;
683 0 : goto out_pm_put;
684 : }
685 :
686 0 : ret = readl_poll_timeout(psys_pdata->base + bootloader_status_offset,
687 : data, data == BOOTLOADER_MAGIC_KEY, 500,
688 : BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
689 : if (ret) {
690 0 : dev_err(&isp->pdev->dev, "Unexpected magic number 0x%x\n",
691 : data);
692 0 : goto out_pm_put;
693 : }
694 :
695 : /*
696 : * Write authenticate_run into IU2CSEDATA0
697 : * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
698 : * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
699 : */
700 0 : dev_info(&isp->pdev->dev, "Sending AUTHENTICATE_RUN to CSE\n");
701 : ret = ipu6_buttress_ipc_send(isp,
702 : BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN,
703 : 1, true,
704 : BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE);
705 0 : if (ret) {
706 0 : dev_err(&isp->pdev->dev, "CSE authenticate_run failed\n");
707 0 : goto out_pm_put;
708 : }
709 :
710 : done = BUTTRESS_SECURITY_CTL_AUTH_DONE;
711 0 : ret = readl_poll_timeout(isp->base + BUTTRESS_REG_SECURITY_CTL, data,
712 : ((data & mask) == done ||
713 : (data & mask) == fail), 500,
714 : BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US);
715 : if (ret) {
716 0 : dev_err(&isp->pdev->dev, "CSE authenticate timeout\n");
717 0 : goto out_pm_put;
718 : }
719 :
720 0 : if ((data & mask) == fail) {
721 0 : dev_err(&isp->pdev->dev, "CSE boot_load failed\n");
722 : ret = -EINVAL;
723 0 : goto out_pm_put;
724 : }
725 :
726 0 : dev_info(&isp->pdev->dev, "CSE authenticate_run done\n");
727 :
728 2 : out_pm_put:
729 2 : pm_runtime_put(&isp->pdev->dev);
730 2 : out_unlock:
731 2 : mutex_unlock(&b->auth_mutex);
732 :
733 2 : return ret;
734 : }
735 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_authenticate, INTEL_IPU6);
736 :
737 1 : static int ipu6_buttress_send_tsc_request(struct ipu6_device *isp)
738 : {
739 : u32 val, mask, done;
740 : int ret;
741 :
742 : mask = IPU4_BUTTRESS_PWR_STATE_HH_STATUS_MASK;
743 :
744 : writel(BUTTRESS_FABRIC_CMD_START_TSC_SYNC,
745 1 : isp->base + BUTTRESS_REG_FABRIC_CMD);
746 :
747 1 : val = readl(isp->base + BUTTRESS_REG_PWR_STATE);
748 : val = FIELD_GET(mask, val);
749 1 : if (val == BUTTRESS_PWR_STATE_HH_STATE_ERR) {
750 0 : dev_err(&isp->pdev->dev, "Start tsc sync failed\n");
751 0 : return -EINVAL;
752 : }
753 :
754 : done = BUTTRESS_PWR_STATE_HH_STATE_DONE;
755 2 : ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATE, val,
756 : FIELD_GET(mask, val) == done, 500,
757 : BUTTRESS_TSC_SYNC_TIMEOUT_US);
758 : if (ret)
759 0 : dev_err(&isp->pdev->dev, "Start tsc sync timeout\n");
760 :
761 : return ret;
762 : }
763 :
764 1 : int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp)
765 : {
766 : unsigned int i;
767 :
768 1 : for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
769 : u32 val;
770 : int ret;
771 :
772 1 : ret = ipu6_buttress_send_tsc_request(isp);
773 1 : if (ret != -ETIMEDOUT)
774 1 : return ret;
775 :
776 0 : val = readl(isp->base + BUTTRESS_REG_TSW_CTL);
777 0 : val = val | BUTTRESS_TSW_CTL_SOFT_RESET;
778 0 : writel(val, isp->base + BUTTRESS_REG_TSW_CTL);
779 : val = val & ~BUTTRESS_TSW_CTL_SOFT_RESET;
780 0 : writel(val, isp->base + BUTTRESS_REG_TSW_CTL);
781 : }
782 :
783 0 : dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n");
784 :
785 0 : return -ETIMEDOUT;
786 : }
787 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_start_tsc_sync, INTEL_IPU6);
788 :
789 2 : void ipu6_buttress_tsc_read(struct ipu6_device *isp, u64 *val)
790 : {
791 : u32 tsc_hi_1, tsc_hi_2, tsc_lo;
792 : unsigned long flags;
793 :
794 : local_irq_save(flags);
795 2 : tsc_hi_1 = readl(isp->base + BUTTRESS_REG_TSC_HI);
796 2 : tsc_lo = readl(isp->base + BUTTRESS_REG_TSC_LO);
797 2 : tsc_hi_2 = readl(isp->base + BUTTRESS_REG_TSC_HI);
798 2 : if (tsc_hi_1 == tsc_hi_2) {
799 2 : *val = (u64)tsc_hi_1 << 32 | tsc_lo;
800 : } else {
801 : /* Check if TSC has rolled over */
802 0 : if (tsc_lo & BIT(31))
803 0 : *val = (u64)tsc_hi_1 << 32 | tsc_lo;
804 : else
805 0 : *val = (u64)tsc_hi_2 << 32 | tsc_lo;
806 : }
807 : local_irq_restore(flags);
808 2 : }
809 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_read, INTEL_IPU6);
810 :
811 2 : u64 ipu6_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu6_device *isp)
812 : {
813 2 : u64 ns = ticks * 10000;
814 :
815 : /*
816 : * converting TSC tick count to ns is calculated by:
817 : * Example (TSC clock frequency is 19.2MHz):
818 : * ns = ticks * 1000 000 000 / 19.2Mhz
819 : * = ticks * 1000 000 000 / 19200000Hz
820 : * = ticks * 10000 / 192 ns
821 : */
822 2 : return div_u64(ns, IPU4_BUTTRESS_TSC_CLOCK_FREQUENCY);
823 : }
824 : EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_ticks_to_ns, INTEL_IPU6);
825 :
826 3 : void ipu6_buttress_restore(struct ipu6_device *isp)
827 : {
828 : struct ipu6_buttress *b = &isp->buttress;
829 :
830 3 : writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_CLEAR);
831 3 : writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE);
832 3 : writel(b->wdt_cached_value, isp->base + BUTTRESS_REG_WDT);
833 3 : }
834 :
835 1 : int ipu6_buttress_init(struct ipu6_device *isp)
836 : {
837 : int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY;
838 : struct ipu6_buttress *b = &isp->buttress;
839 : u32 val;
840 :
841 1 : mutex_init(&b->power_mutex);
842 1 : mutex_init(&b->auth_mutex);
843 1 : mutex_init(&b->cons_mutex);
844 1 : mutex_init(&b->ipc_mutex);
845 : init_completion(&b->cse.send_complete);
846 : init_completion(&b->cse.recv_complete);
847 :
848 1 : b->cse.nack = BUTTRESS_CSE2IUDATA0_IPC_NACK;
849 1 : b->cse.nack_mask = BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK;
850 1 : b->cse.csr_in = BUTTRESS_REG_CSE2IUCSR;
851 1 : b->cse.csr_out = BUTTRESS_REG_IU2CSECSR;
852 1 : b->cse.db0_in = BUTTRESS_REG_CSE2IUDB0;
853 1 : b->cse.db0_out = BUTTRESS_REG_IU2CSEDB0;
854 1 : b->cse.data0_in = BUTTRESS_REG_CSE2IUDATA0;
855 1 : b->cse.data0_out = BUTTRESS_REG_IU2CSEDATA0;
856 :
857 :
858 1 : isp->secure_mode = ipu6_buttress_get_secure_mode(isp);
859 1 : dev_dbg(&isp->pdev->dev, "IPU6 in %s mode touch 0x%x mask 0x%x\n",
860 : isp->secure_mode ? "secure" : "non-secure",
861 : readl(isp->base + BUTTRESS_REG_SECURITY_TOUCH),
862 : readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
863 :
864 1 : b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_WDT);
865 1 : writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_CLEAR);
866 1 : writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_ENABLE);
867 :
868 : /* get ref_clk frequency by reading the indication in btrs control */
869 1 : val = readl(isp->base + BUTTRESS_REG_BTRS_CTRL);
870 1 : val = FIELD_GET(BUTTRESS_REG_BTRS_CTRL_REF_CLK_IND, val);
871 :
872 1 : switch (val) {
873 1 : case 0x0:
874 1 : b->ref_clk = 240;
875 1 : break;
876 0 : case 0x1:
877 0 : b->ref_clk = 192;
878 0 : break;
879 0 : case 0x2:
880 0 : b->ref_clk = 384;
881 0 : break;
882 0 : default:
883 0 : dev_warn(&isp->pdev->dev,
884 : "Unsupported ref clock, use 19.2Mhz by default.\n");
885 0 : b->ref_clk = 192;
886 0 : break;
887 : }
888 :
889 : /* Retry couple of times in case of CSE initialization is delayed */
890 : do {
891 1 : ret = ipu6_buttress_ipc_reset(isp, &b->cse);
892 1 : if (ret) {
893 0 : dev_warn(&isp->pdev->dev,
894 : "IPC reset protocol failed, retrying\n");
895 : } else {
896 1 : dev_dbg(&isp->pdev->dev, "IPC reset done\n");
897 1 : return 0;
898 : }
899 0 : } while (ipc_reset_retry--);
900 :
901 0 : dev_err(&isp->pdev->dev, "IPC reset protocol failed\n");
902 :
903 : mutex_destroy(&b->power_mutex);
904 : mutex_destroy(&b->auth_mutex);
905 : mutex_destroy(&b->cons_mutex);
906 : mutex_destroy(&b->ipc_mutex);
907 :
908 0 : return ret;
909 : }
910 :
911 0 : void ipu6_buttress_exit(struct ipu6_device *isp)
912 : {
913 : struct ipu6_buttress *b = &isp->buttress;
914 :
915 0 : writel(0, isp->base + BUTTRESS_REG_ISR_ENABLE);
916 :
917 : mutex_destroy(&b->power_mutex);
918 : mutex_destroy(&b->auth_mutex);
919 : mutex_destroy(&b->cons_mutex);
920 : mutex_destroy(&b->ipc_mutex);
921 0 : }
|