video: tegra: host: add DT support
[linux-2.6.git] / drivers / video / tegra / host / tsec / tsec.c
1 /*
2  * drivers/video/tegra/host/tsec/tsec.c
3  *
4  * Tegra TSEC Module Support
5  *
6  * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/slab.h>         /* for kzalloc */
22 #include <linux/firmware.h>
23 #include <linux/module.h>
24 #include <linux/pm_runtime.h>
25 #include <mach/clk.h>
26 #include <asm/byteorder.h>      /* for parsing ucode image wrt endianness */
27 #include <linux/delay.h>        /* for udelay */
28 #include <linux/scatterlist.h>
29 #include <linux/stop_machine.h>
30 #include <linux/of.h>
31 #include <linux/of_device.h>
32 #include <linux/of_platform.h>
33 #include "dev.h"
34 #include "tsec.h"
35 #include "hw_tsec.h"
36 #include "bus_client.h"
37 #include "nvhost_acm.h"
38 #include "chip_support.h"
39 #include "nvhost_memmgr.h"
40 #include "nvhost_intr.h"
41 #include "t114/t114.h"
42
43 #define TSEC_IDLE_TIMEOUT_DEFAULT       10000   /* 10 milliseconds */
44 #define TSEC_IDLE_CHECK_PERIOD          10      /* 10 usec */
45 #define TSEC_KEY_LENGTH                 16
46 #define TSEC_RESERVE                    256
47 #define TSEC_KEY_OFFSET                 (TSEC_RESERVE - TSEC_KEY_LENGTH)
48 #define TSEC_HOST1X_STATUS_OFFSET       (TSEC_KEY_OFFSET - 4)
49
50 #define TSEC_OS_START_OFFSET    256
51
52 #define get_tsec(ndev) ((struct tsec *)(ndev)->dev.platform_data)
53 #define set_tsec(ndev, f) ((ndev)->dev.platform_data = f)
54
55 /* The key value in ascii hex */
56 static u8 otf_key[TSEC_KEY_LENGTH];
57
58 /* Pointer to this device */
59 struct platform_device *tsec;
60
61 static u32 *host1x_status_offset(struct tsec *m)
62 {
63         return (u32 *)
64                 &(m->mapped[m->os.reserved_offset + TSEC_HOST1X_STATUS_OFFSET]);
65 }
66
67 static u32 tsec_get_host1x_state(void)
68 {
69         struct tsec *m = get_tsec(tsec);
70         u32 ret;
71
72         /* We have dedicated memory byte  */
73         ret = *host1x_status_offset(m);
74         rmb();
75         return ret;
76 }
77
78 static void tsec_set_host1x_state(int state)
79 {
80         struct tsec *m = get_tsec(tsec);
81
82         *host1x_status_offset(m) = state;
83         wmb();
84 }
85
86 static int stop_machine_fn(void *priv)
87 {
88         int timeout = 10000;
89
90         tsec_set_host1x_state(tsec_host1x_access_granted);
91
92         while (tsec_get_host1x_state() != tsec_host1x_release_access
93                         && timeout)
94                 timeout--;
95
96         if (!timeout)
97                 pr_err("TSEC didn't release access");
98
99         tsec_set_host1x_state(tsec_host1x_none);
100
101         return 0;
102 }
103
104 static void disable_tsec_irq(struct platform_device *pdev)
105 {
106         nvhost_intr_disable_general_irq(&nvhost_get_host(pdev)->intr, 20);
107 }
108
109 static void enable_tsec_irq(struct platform_device *pdev)
110 {
111         /* Clear interrupt */
112         nvhost_device_writel(pdev, tsec_irqsclr_r(), 0xffffff);
113         nvhost_device_writel(pdev, tsec_thi_int_status_r(), 0x1);
114         nvhost_intr_enable_general_irq(&nvhost_get_host(pdev)->intr, 20,
115                         nvhost_tsec_isr, nvhost_tsec_isr_thread);
116 }
117
118 void nvhost_tsec_isr(void)
119 {
120         disable_tsec_irq(tsec);
121 }
122
123 void nvhost_tsec_isr_thread(void)
124 {
125         if (tsec_get_host1x_state() == tsec_host1x_request_access)
126                 stop_machine(stop_machine_fn, NULL, NULL);
127         enable_tsec_irq(tsec);
128 }
129
130 /* caller is responsible for freeing */
131 static char *tsec_get_fw_name(struct platform_device *dev)
132 {
133         char *fw_name;
134         u8 maj, min;
135         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
136
137         /* note size here is a little over...*/
138         fw_name = kzalloc(32, GFP_KERNEL);
139         if (!fw_name)
140                 return NULL;
141
142         decode_tsec_ver(pdata->version, &maj, &min);
143         if (maj == 1) {
144                 /* there are no minor versions so far for maj==1 */
145                 sprintf(fw_name, "nvhost_tsec.fw");
146         } else {
147                 kfree(fw_name);
148                 return NULL;
149         }
150
151         dev_info(&dev->dev, "fw name:%s\n", fw_name);
152
153         return fw_name;
154 }
155
156 static int tsec_dma_wait_idle(struct platform_device *dev, u32 *timeout)
157 {
158         if (!*timeout)
159                 *timeout = TSEC_IDLE_TIMEOUT_DEFAULT;
160
161         do {
162                 u32 check = min_t(u32, TSEC_IDLE_CHECK_PERIOD, *timeout);
163                 u32 dmatrfcmd = nvhost_device_readl(dev, tsec_dmatrfcmd_r());
164                 u32 idle_v = tsec_dmatrfcmd_idle_v(dmatrfcmd);
165
166                 if (tsec_dmatrfcmd_idle_true_v() == idle_v)
167                         return 0;
168
169                 udelay(TSEC_IDLE_CHECK_PERIOD);
170                 *timeout -= check;
171         } while (*timeout);
172
173         dev_err(&dev->dev, "dma idle timeout");
174
175         return -1;
176 }
177
178 static int tsec_dma_pa_to_internal_256b(struct platform_device *dev,
179                 u32 offset, u32 internal_offset, bool imem)
180 {
181         u32 cmd = tsec_dmatrfcmd_size_256b_f();
182         u32 pa_offset =  tsec_dmatrffboffs_offs_f(offset);
183         u32 i_offset = tsec_dmatrfmoffs_offs_f(internal_offset);
184         u32 timeout = 0; /* default*/
185
186         if (imem)
187                 cmd |= tsec_dmatrfcmd_imem_true_f();
188
189         nvhost_device_writel(dev, tsec_dmatrfmoffs_r(), i_offset);
190         nvhost_device_writel(dev, tsec_dmatrffboffs_r(), pa_offset);
191         nvhost_device_writel(dev, tsec_dmatrfcmd_r(), cmd);
192
193         return tsec_dma_wait_idle(dev, &timeout);
194
195 }
196
197 static int tsec_wait_idle(struct platform_device *dev, u32 *timeout)
198 {
199         if (!*timeout)
200                 *timeout = TSEC_IDLE_TIMEOUT_DEFAULT;
201
202         do {
203                 u32 check = min_t(u32, TSEC_IDLE_CHECK_PERIOD, *timeout);
204                 u32 w = nvhost_device_readl(dev, tsec_idlestate_r());
205
206                 if (!w)
207                         return 0;
208                 udelay(TSEC_IDLE_CHECK_PERIOD);
209                 *timeout -= check;
210         } while (*timeout);
211
212         return -1;
213 }
214
215 static int tsec_load_kfuse(struct platform_device *pdev)
216 {
217         u32 val;
218         u32 timeout;
219
220         val = nvhost_device_readl(pdev, tsec_tegra_ctl_r());
221         val &= ~tsec_tegra_ctl_tkfi_kfuse_m();
222         nvhost_device_writel(pdev, tsec_tegra_ctl_r(), val);
223
224         val = nvhost_device_readl(pdev, tsec_scp_ctl_pkey_r());
225         val |= tsec_scp_ctl_pkey_request_reload_s();
226         nvhost_device_writel(pdev, tsec_scp_ctl_pkey_r(), val);
227
228         timeout = TSEC_IDLE_TIMEOUT_DEFAULT;
229
230         do {
231                 u32 check = min_t(u32, TSEC_IDLE_CHECK_PERIOD, timeout);
232                 u32 w = nvhost_device_readl(pdev, tsec_scp_ctl_pkey_r());
233
234                 if (w & tsec_scp_ctl_pkey_loaded_m())
235                         break;
236                 udelay(TSEC_IDLE_CHECK_PERIOD);
237                 timeout -= check;
238         } while (timeout);
239
240         val = nvhost_device_readl(pdev, tsec_tegra_ctl_r());
241         val |= tsec_tegra_ctl_tkfi_kfuse_m();
242         nvhost_device_writel(pdev, tsec_tegra_ctl_r(), val);
243
244         if (timeout)
245                 return 0;
246         else
247                 return -1;
248 }
249
250 int tsec_boot(struct platform_device *dev)
251 {
252         u32 timeout;
253         u32 offset;
254         int err = 0;
255         struct tsec *m = get_tsec(dev);
256
257         nvhost_device_writel(dev, tsec_dmactl_r(), 0);
258         nvhost_device_writel(dev, tsec_dmatrfbase_r(),
259                 (sg_dma_address(m->pa->sgl) + m->os.bin_data_offset) >> 8);
260
261         for (offset = 0; offset < m->os.data_size; offset += 256)
262                 tsec_dma_pa_to_internal_256b(dev,
263                                            m->os.data_offset + offset,
264                                            offset, false);
265
266         tsec_dma_pa_to_internal_256b(dev,
267                                      m->os.code_offset+TSEC_OS_START_OFFSET,
268                                      TSEC_OS_START_OFFSET, true);
269
270
271         /* boot tsec */
272         nvhost_device_writel(dev, tsec_bootvec_r(),
273                              tsec_bootvec_vec_f(TSEC_OS_START_OFFSET));
274         nvhost_device_writel(dev, tsec_cpuctl_r(),
275                         tsec_cpuctl_startcpu_true_f());
276
277         timeout = 0; /* default */
278
279         err = tsec_wait_idle(dev, &timeout);
280         if (err != 0) {
281                 dev_err(&dev->dev, "boot failed due to timeout");
282                 return err;
283         }
284
285         /* setup tsec interrupts and enable interface */
286         nvhost_device_writel(dev, tsec_irqmset_r(),
287                         (tsec_irqmset_ext_f(0xff) |
288                                 tsec_irqmset_swgen1_set_f() |
289                                 tsec_irqmset_swgen0_set_f() |
290                                 tsec_irqmset_exterr_set_f() |
291                                 tsec_irqmset_halt_set_f()   |
292                                 tsec_irqmset_wdtmr_set_f()));
293
294         nvhost_device_writel(dev, tsec_itfen_r(),
295                         (tsec_itfen_mthden_enable_f() |
296                                 tsec_itfen_ctxen_enable_f()));
297
298         return tsec_load_kfuse(dev);
299 }
300
301 static int tsec_setup_ucode_image(struct platform_device *dev,
302                 u32 *ucode_ptr,
303                 const struct firmware *ucode_fw)
304 {
305         struct tsec *m = get_tsec(dev);
306         /* image data is little endian. */
307         struct tsec_ucode_v1 ucode;
308         int w;
309         u32 reserved_offset;
310         u32 tsec_key_offset;
311
312         /* copy the whole thing taking into account endianness */
313         for (w = 0; w < ucode_fw->size / sizeof(u32); w++)
314                 ucode_ptr[w] = le32_to_cpu(((u32 *)ucode_fw->data)[w]);
315
316         ucode.bin_header = (struct tsec_ucode_bin_header_v1 *)ucode_ptr;
317         /* endian problems would show up right here */
318         if (ucode.bin_header->bin_magic != 0x10de) {
319                 dev_err(&dev->dev,
320                            "failed to get firmware magic");
321                 return -EINVAL;
322         }
323         if (ucode.bin_header->bin_ver != 1) {
324                 dev_err(&dev->dev,
325                            "unsupported firmware version");
326                 return -ENOENT;
327         }
328         /* shouldn't be bigger than what firmware thinks */
329         if (ucode.bin_header->bin_size > ucode_fw->size) {
330                 dev_err(&dev->dev,
331                            "ucode image size inconsistency");
332                 return -EINVAL;
333         }
334
335         dev_dbg(&dev->dev,
336                 "ucode bin header: magic:0x%x ver:%d size:%d\n",
337                 ucode.bin_header->bin_magic,
338                 ucode.bin_header->bin_ver,
339                 ucode.bin_header->bin_size);
340         dev_dbg(&dev->dev,
341                 "ucode bin header: os bin (header,data) offset size: 0x%x, 0x%x %d\n",
342                 ucode.bin_header->os_bin_header_offset,
343                 ucode.bin_header->os_bin_data_offset,
344                 ucode.bin_header->os_bin_size);
345         ucode.os_header = (struct tsec_ucode_os_header_v1 *)
346                 (((void *)ucode_ptr) + ucode.bin_header->os_bin_header_offset);
347
348         dev_dbg(&dev->dev,
349                 "os ucode header: os code (offset,size): 0x%x, 0x%x\n",
350                 ucode.os_header->os_code_offset,
351                 ucode.os_header->os_code_size);
352         dev_dbg(&dev->dev,
353                 "os ucode header: os data (offset,size): 0x%x, 0x%x\n",
354                 ucode.os_header->os_data_offset,
355                 ucode.os_header->os_data_size);
356         dev_dbg(&dev->dev,
357                 "os ucode header: num apps: %d\n",
358                 ucode.os_header->num_apps);
359
360         /* make space for reserved area - we need 20 bytes, but we move 256
361          * bytes because firmware needs to be 256 byte aligned */
362         reserved_offset = ucode.bin_header->os_bin_data_offset;
363         memmove(((void *)ucode_ptr) + reserved_offset + TSEC_RESERVE,
364                         ((void *)ucode_ptr) + reserved_offset,
365                         ucode.bin_header->os_bin_size);
366         ucode.bin_header->os_bin_data_offset += TSEC_RESERVE;
367
368         /*  clear 256 bytes before ucode os code */
369         memset(((void *)ucode_ptr) + reserved_offset, 0, TSEC_RESERVE);
370
371         /* Copy key to be the 16 bytes before the firmware */
372         tsec_key_offset = reserved_offset + TSEC_KEY_OFFSET;
373         memcpy(((void *)ucode_ptr) + tsec_key_offset, otf_key, TSEC_KEY_LENGTH);
374
375         m->os.size = ucode.bin_header->os_bin_size;
376         m->os.reserved_offset = reserved_offset;
377         m->os.bin_data_offset = ucode.bin_header->os_bin_data_offset;
378         m->os.code_offset = ucode.os_header->os_code_offset;
379         m->os.data_offset = ucode.os_header->os_data_offset;
380         m->os.data_size   = ucode.os_header->os_data_size;
381
382         return 0;
383 }
384
385 int tsec_read_ucode(struct platform_device *dev, const char *fw_name)
386 {
387         struct tsec *m = get_tsec(dev);
388         const struct firmware *ucode_fw;
389         int err;
390
391         ucode_fw = nvhost_client_request_firmware(dev, fw_name);
392         if (IS_ERR_OR_NULL(ucode_fw)) {
393                 dev_err(&dev->dev, "failed to get tsec firmware\n");
394                 err = -ENOENT;
395                 return err;
396         }
397
398         /* allocate pages for ucode */
399         m->mem_r = mem_op().alloc(nvhost_get_host(dev)->memmgr,
400                              roundup(ucode_fw->size+256, PAGE_SIZE),
401                              PAGE_SIZE, mem_mgr_flag_uncacheable);
402         if (IS_ERR_OR_NULL(m->mem_r)) {
403                 dev_err(&dev->dev, "nvmap alloc failed");
404                 err = -ENOMEM;
405                 goto clean_up;
406         }
407
408         m->pa = mem_op().pin(nvhost_get_host(dev)->memmgr, m->mem_r);
409         if (IS_ERR_OR_NULL(m->pa)) {
410                 dev_err(&dev->dev, "nvmap pin failed for ucode");
411                 err = PTR_ERR(m->pa);
412                 m->pa = 0;
413                 goto clean_up;
414         }
415
416         m->mapped = mem_op().mmap(m->mem_r);
417         if (IS_ERR_OR_NULL(m->mapped)) {
418                 dev_err(&dev->dev, "nvmap mmap failed");
419                 err = -ENOMEM;
420                 goto clean_up;
421         }
422
423         err = tsec_setup_ucode_image(dev, (u32 *)m->mapped, ucode_fw);
424         if (err) {
425                 dev_err(&dev->dev, "failed to parse firmware image\n");
426                 return err;
427         }
428
429         m->valid = true;
430
431         release_firmware(ucode_fw);
432
433         return 0;
434
435 clean_up:
436         if (m->mapped) {
437                 mem_op().munmap(m->mem_r, m->mapped);
438                 m->mapped = NULL;
439         }
440         if (m->pa) {
441                 mem_op().unpin(nvhost_get_host(dev)->memmgr, m->mem_r, m->pa);
442                 m->pa = NULL;
443         }
444         if (m->mem_r) {
445                 mem_op().put(nvhost_get_host(dev)->memmgr, m->mem_r);
446                 m->mem_r = NULL;
447         }
448         release_firmware(ucode_fw);
449         return err;
450 }
451
452 void nvhost_tsec_init(struct platform_device *dev)
453 {
454         int err = 0;
455         struct tsec *m;
456         char *fw_name;
457
458         fw_name = tsec_get_fw_name(dev);
459         if (!fw_name) {
460                 dev_err(&dev->dev, "couldn't determine firmware name");
461                 return;
462         }
463
464         m = kzalloc(sizeof(struct tsec), GFP_KERNEL);
465         if (!m) {
466                 dev_err(&dev->dev, "couldn't alloc ucode");
467                 kfree(fw_name);
468                 return;
469         }
470         set_tsec(dev, m);
471
472         err = tsec_read_ucode(dev, fw_name);
473         kfree(fw_name);
474         fw_name = 0;
475
476         if (err || !m->valid) {
477                 dev_err(&dev->dev, "ucode not valid");
478                 goto clean_up;
479         }
480
481         nvhost_module_busy(dev);
482
483         tsec_boot(dev);
484         enable_tsec_irq(dev);
485         nvhost_module_idle(dev);
486         return;
487
488 clean_up:
489         dev_err(&dev->dev, "failed");
490 }
491
492 void nvhost_tsec_deinit(struct platform_device *dev)
493 {
494         struct tsec *m = get_tsec(dev);
495
496         disable_tsec_irq(dev);
497
498         /* unpin, free ucode memory */
499         if (m->mem_r) {
500                 if (m->mapped)
501                         mem_op().munmap(m->mem_r, m->mapped);
502                 if (m->pa)
503                         mem_op().unpin(nvhost_get_host(dev)->memmgr, m->mem_r,
504                                 m->pa);
505                 if (m->mem_r)
506                         mem_op().put(nvhost_get_host(dev)->memmgr, m->mem_r);
507                 m->mem_r = 0;
508         }
509 }
510
511 void nvhost_tsec_finalize_poweron(struct platform_device *dev)
512 {
513         tsec_boot(dev);
514 }
515
516 static struct of_device_id tegra_tsec_of_match[] __devinitdata = {
517         { .compatible = "nvidia,tegra114-tsec",
518                 .data = (struct nvhost_device_data *)&t11_tsec_info },
519         { },
520 };
521 static int __devinit tsec_probe(struct platform_device *dev)
522 {
523         int err;
524         struct nvhost_device_data *pdata = NULL;
525
526         if (dev->dev.of_node) {
527                 const struct of_device_id *match;
528
529                 match = of_match_device(tegra_tsec_of_match, &dev->dev);
530                 if (match)
531                         pdata = (struct nvhost_device_data *)match->data;
532         } else
533                 pdata = (struct nvhost_device_data *)dev->dev.platform_data;
534
535         WARN_ON(!pdata);
536         if (!pdata) {
537                 dev_info(&dev->dev, "no platform data\n");
538                 return -ENODATA;
539         }
540
541         pdata->pdev = dev;
542         pdata->init = nvhost_tsec_init;
543         pdata->deinit = nvhost_tsec_deinit;
544
545         platform_set_drvdata(dev, pdata);
546
547         err = nvhost_client_device_get_resources(dev);
548         if (err)
549                 return err;
550
551         tsec = dev;
552
553         err = nvhost_client_device_init(dev);
554         if (err)
555                 return err;
556
557         nvhost_module_busy(to_platform_device(dev->dev.parent));
558
559         /* Reset TSEC at boot-up. Otherwise it starts sending interrupts. */
560         clk_enable(pdata->clk[0]);
561         tegra_periph_reset_assert(pdata->clk[0]);
562         udelay(10);
563         tegra_periph_reset_deassert(pdata->clk[0]);
564         clk_disable(pdata->clk[0]);
565
566         pm_runtime_use_autosuspend(&dev->dev);
567         pm_runtime_set_autosuspend_delay(&dev->dev, 100);
568         pm_runtime_enable(&dev->dev);
569
570         nvhost_module_idle(to_platform_device(dev->dev.parent));
571         return err;
572 }
573
574 static int __exit tsec_remove(struct platform_device *dev)
575 {
576         struct nvhost_master *host = nvhost_get_host(dev);
577
578         /* Add clean-up */
579         host->intr.generic_isr[20] = NULL;
580         host->intr.generic_isr_thread[20] = NULL;
581         return 0;
582 }
583
584 #ifdef CONFIG_PM
585 static int tsec_suspend(struct platform_device *dev, pm_message_t state)
586 {
587         return nvhost_client_device_suspend(dev);
588 }
589
590 static int tsec_resume(struct platform_device *dev)
591 {
592         dev_info(&dev->dev, "resuming\n");
593         return 0;
594 }
595 #endif
596
597 static struct platform_driver tsec_driver = {
598         .probe = tsec_probe,
599         .remove = __exit_p(tsec_remove),
600 #ifdef CONFIG_PM
601         .suspend = tsec_suspend,
602         .resume = tsec_resume,
603 #endif
604         .driver = {
605                 .owner = THIS_MODULE,
606                 .name = "tsec",
607 #ifdef CONFIG_OF
608                 .of_match_table = tegra_tsec_of_match,
609 #endif
610         }
611 };
612
613 static int __init tsec_key_setup(char *line)
614 {
615         int i;
616         u8 tmp[] = {0,0,0};
617         pr_debug("tsec otf key: %s\n", line);
618
619         if (strlen(line) != TSEC_KEY_LENGTH*2) {
620                 pr_warn("invalid tsec key: %s\n", line);
621                 return 0;
622         }
623
624         for (i = 0; i < TSEC_KEY_LENGTH; i++) {
625                 int err;
626                 memcpy(tmp, &line[i*2], 2);
627                 err = kstrtou8(tmp, 16, &otf_key[i]);
628                 if (err) {
629                         pr_warn("cannot read tsec otf key: %d", err);
630                         break;
631                 }
632         }
633         return 0;
634 }
635 __setup("otf_key=", tsec_key_setup);
636
637 static int __init tsec_init(void)
638 {
639         return platform_driver_register(&tsec_driver);
640 }
641
642 static void __exit tsec_exit(void)
643 {
644         platform_driver_unregister(&tsec_driver);
645 }
646
647 module_init(tsec_init);
648 module_exit(tsec_exit);