video: tegra: host: Separate gk20a configs
[linux-3.10.git] / drivers / video / tegra / host / gk20a / gk20a.c
1 /*
2  * drivers/video/tegra/host/gk20a/gk20a.c
3  *
4  * GK20A Graphics
5  *
6  * Copyright (c) 2011-2014, 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/highmem.h>
22 #include <linux/cdev.h>
23 #include <linux/delay.h>
24 #include <linux/firmware.h>
25 #include <linux/interrupt.h>
26 #include <linux/irq.h>
27 #include <linux/export.h>
28 #include <linux/of.h>
29 #include <linux/of_device.h>
30 #include <linux/of_platform.h>
31 #include <linux/thermal.h>
32 #include <asm/cacheflush.h>
33 #include <linux/debugfs.h>
34 #include <linux/spinlock.h>
35 #include <linux/tegra-powergate.h>
36
37 #include <linux/suspend.h>
38 #include <linux/sched.h>
39 #include <linux/input-cfboost.h>
40
41 #include <mach/pm_domains.h>
42
43 #include "dev.h"
44 #include "class_ids.h"
45 #include "bus_client.h"
46 #include "nvhost_as.h"
47
48 #include "gk20a.h"
49 #include "ctrl_gk20a.h"
50 #include "hw_mc_gk20a.h"
51 #include "hw_timer_gk20a.h"
52 #include "hw_bus_gk20a.h"
53 #include "hw_sim_gk20a.h"
54 #include "hw_top_gk20a.h"
55 #include "hw_ltc_gk20a.h"
56 #include "gk20a_scale.h"
57 #include "gr3d/pod_scaling.h"
58 #include "dbg_gpu_gk20a.h"
59
60 #include "../../../../../arch/arm/mach-tegra/iomap.h"
61
62 static inline void set_gk20a(struct platform_device *dev, struct gk20a *gk20a)
63 {
64         nvhost_set_private_data(dev, gk20a);
65 }
66
67 /* TBD: should be able to put in the list below. */
68 static struct resource gk20a_intr = {
69         .start = TEGRA_GK20A_INTR,
70         .end   = TEGRA_GK20A_INTR_NONSTALL,
71         .flags = IORESOURCE_IRQ,
72 };
73
74 struct resource gk20a_resources_sim[] = {
75         {
76         .start = TEGRA_GK20A_BAR0_BASE,
77         .end   = TEGRA_GK20A_BAR0_BASE + TEGRA_GK20A_BAR0_SIZE - 1,
78         .flags = IORESOURCE_MEM,
79         },
80         {
81         .start = TEGRA_GK20A_BAR1_BASE,
82         .end   = TEGRA_GK20A_BAR1_BASE + TEGRA_GK20A_BAR1_SIZE - 1,
83         .flags = IORESOURCE_MEM,
84         },
85         {
86         .start = TEGRA_GK20A_SIM_BASE,
87         .end   = TEGRA_GK20A_SIM_BASE + TEGRA_GK20A_SIM_SIZE - 1,
88         .flags = IORESOURCE_MEM,
89         },
90 };
91
92 const struct file_operations tegra_gk20a_ctrl_ops = {
93         .owner = THIS_MODULE,
94         .release = gk20a_ctrl_dev_release,
95         .open = gk20a_ctrl_dev_open,
96         .unlocked_ioctl = gk20a_ctrl_dev_ioctl,
97 };
98
99 const struct file_operations tegra_gk20a_dbg_gpu_ops = {
100         .owner = THIS_MODULE,
101         .release        = gk20a_dbg_gpu_dev_release,
102         .open           = gk20a_dbg_gpu_dev_open,
103         .unlocked_ioctl = gk20a_dbg_gpu_dev_ioctl,
104         .poll           = gk20a_dbg_gpu_dev_poll,
105 #ifdef CONFIG_COMPAT
106         .compat_ioctl = gk20a_dbg_gpu_dev_ioctl,
107 #endif
108 };
109
110 /*
111  * Note: We use a different 'open' to trigger handling of the profiler session.
112  * Most of the code is shared between them...  Though, at some point if the
113  * code does get too tangled trying to handle each in the same path we can
114  * separate them cleanly.
115  */
116 const struct file_operations tegra_gk20a_prof_gpu_ops = {
117         .owner = THIS_MODULE,
118         .release        = gk20a_dbg_gpu_dev_release,
119         .open           = gk20a_prof_gpu_dev_open,
120         .unlocked_ioctl = gk20a_dbg_gpu_dev_ioctl,
121         /* .mmap           = gk20a_prof_gpu_dev_mmap,*/
122         /*int (*mmap) (struct file *, struct vm_area_struct *);*/
123         .compat_ioctl = gk20a_dbg_gpu_dev_ioctl,
124 #ifdef CONFIG_COMPAT
125         .compat_ioctl = gk20a_dbg_gpu_dev_ioctl,
126 #endif
127 };
128
129
130 static inline void sim_writel(struct gk20a *g, u32 r, u32 v)
131 {
132         writel(v, g->sim.regs+r);
133 }
134
135 static inline u32 sim_readl(struct gk20a *g, u32 r)
136 {
137         return readl(g->sim.regs+r);
138 }
139
140 static void kunmap_and_free_iopage(void **kvaddr, struct page **page)
141 {
142         if (*kvaddr) {
143                 kunmap(*kvaddr);
144                 *kvaddr = 0;
145         }
146         if (*page) {
147                 __free_page(*page);
148                 *page = 0;
149         }
150 }
151
152 static void gk20a_free_sim_support(struct gk20a *g)
153 {
154         /* free sim mappings, bfrs */
155         kunmap_and_free_iopage(&g->sim.send_bfr.kvaddr,
156                                &g->sim.send_bfr.page);
157
158         kunmap_and_free_iopage(&g->sim.recv_bfr.kvaddr,
159                                &g->sim.recv_bfr.page);
160
161         kunmap_and_free_iopage(&g->sim.msg_bfr.kvaddr,
162                                &g->sim.msg_bfr.page);
163 }
164
165 static void gk20a_remove_sim_support(struct sim_gk20a *s)
166 {
167         struct gk20a *g = s->g;
168         if (g->sim.regs)
169                 sim_writel(g, sim_config_r(), sim_config_mode_disabled_v());
170         gk20a_free_sim_support(g);
171 }
172
173 static int alloc_and_kmap_iopage(struct device *d,
174                                  void **kvaddr,
175                                  phys_addr_t *phys,
176                                  struct page **page)
177 {
178         int err = 0;
179         *page = alloc_page(GFP_KERNEL);
180
181         if (!*page) {
182                 err = -ENOMEM;
183                 dev_err(d, "couldn't allocate io page\n");
184                 goto fail;
185         }
186
187         *kvaddr = kmap(*page);
188         if (!*kvaddr) {
189                 err = -ENOMEM;
190                 dev_err(d, "couldn't kmap io page\n");
191                 goto fail;
192         }
193         *phys = page_to_phys(*page);
194         return 0;
195
196  fail:
197         kunmap_and_free_iopage(kvaddr, page);
198         return err;
199
200 }
201 /* TBD: strip from released */
202 static int gk20a_init_sim_support(struct platform_device *dev)
203 {
204         int err = 0;
205         struct gk20a *g = get_gk20a(dev);
206         struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
207         struct device *d = &dev->dev;
208         phys_addr_t phys;
209
210         g->sim.g = g;
211         g->sim.regs = pdata->aperture[GK20A_SIM_IORESOURCE_MEM];
212         if (!g->sim.regs) {
213                 dev_err(d, "failed to remap gk20a sim regs\n");
214                 err = -ENXIO;
215                 goto fail;
216         }
217
218         /* allocate sim event/msg buffers */
219         err = alloc_and_kmap_iopage(d, &g->sim.send_bfr.kvaddr,
220                                     &g->sim.send_bfr.phys,
221                                     &g->sim.send_bfr.page);
222
223         err = err || alloc_and_kmap_iopage(d, &g->sim.recv_bfr.kvaddr,
224                                            &g->sim.recv_bfr.phys,
225                                            &g->sim.recv_bfr.page);
226
227         err = err || alloc_and_kmap_iopage(d, &g->sim.msg_bfr.kvaddr,
228                                            &g->sim.msg_bfr.phys,
229                                            &g->sim.msg_bfr.page);
230
231         if (!(g->sim.send_bfr.kvaddr && g->sim.recv_bfr.kvaddr &&
232               g->sim.msg_bfr.kvaddr)) {
233                 dev_err(d, "couldn't allocate all sim buffers\n");
234                 goto fail;
235         }
236
237         /*mark send ring invalid*/
238         sim_writel(g, sim_send_ring_r(), sim_send_ring_status_invalid_f());
239
240         /*read get pointer and make equal to put*/
241         g->sim.send_ring_put = sim_readl(g, sim_send_get_r());
242         sim_writel(g, sim_send_put_r(), g->sim.send_ring_put);
243
244         /*write send ring address and make it valid*/
245         /*TBD: work for >32b physmem*/
246         phys = g->sim.send_bfr.phys;
247         sim_writel(g, sim_send_ring_hi_r(), 0);
248         sim_writel(g, sim_send_ring_r(),
249                    sim_send_ring_status_valid_f() |
250                    sim_send_ring_target_phys_pci_coherent_f() |
251                    sim_send_ring_size_4kb_f() |
252                    sim_send_ring_addr_lo_f(phys >> PAGE_SHIFT));
253
254         /*repeat for recv ring (but swap put,get as roles are opposite) */
255         sim_writel(g, sim_recv_ring_r(), sim_recv_ring_status_invalid_f());
256
257         /*read put pointer and make equal to get*/
258         g->sim.recv_ring_get = sim_readl(g, sim_recv_put_r());
259         sim_writel(g, sim_recv_get_r(), g->sim.recv_ring_get);
260
261         /*write send ring address and make it valid*/
262         /*TBD: work for >32b physmem*/
263         phys = g->sim.recv_bfr.phys;
264         sim_writel(g, sim_recv_ring_hi_r(), 0);
265         sim_writel(g, sim_recv_ring_r(),
266                    sim_recv_ring_status_valid_f() |
267                    sim_recv_ring_target_phys_pci_coherent_f() |
268                    sim_recv_ring_size_4kb_f() |
269                    sim_recv_ring_addr_lo_f(phys >> PAGE_SHIFT));
270
271         g->sim.remove_support = gk20a_remove_sim_support;
272         return 0;
273
274  fail:
275         gk20a_free_sim_support(g);
276         return err;
277 }
278
279 static inline u32 sim_msg_header_size(void)
280 {
281         return 24;/*TBD: fix the header to gt this from NV_VGPU_MSG_HEADER*/
282 }
283
284 static inline u32 *sim_msg_bfr(struct gk20a *g, u32 byte_offset)
285 {
286         return (u32 *)(g->sim.msg_bfr.kvaddr + byte_offset);
287 }
288
289 static inline u32 *sim_msg_hdr(struct gk20a *g, u32 byte_offset)
290 {
291         return sim_msg_bfr(g, byte_offset); /*starts at 0*/
292 }
293
294 static inline u32 *sim_msg_param(struct gk20a *g, u32 byte_offset)
295 {
296         /*starts after msg header/cmn*/
297         return sim_msg_bfr(g, byte_offset + sim_msg_header_size());
298 }
299
300 static inline void sim_write_hdr(struct gk20a *g, u32 func, u32 size)
301 {
302         /*memset(g->sim.msg_bfr.kvaddr,0,min(PAGE_SIZE,size));*/
303         *sim_msg_hdr(g, sim_msg_signature_r()) = sim_msg_signature_valid_v();
304         *sim_msg_hdr(g, sim_msg_result_r())    = sim_msg_result_rpc_pending_v();
305         *sim_msg_hdr(g, sim_msg_spare_r())     = sim_msg_spare__init_v();
306         *sim_msg_hdr(g, sim_msg_function_r())  = func;
307         *sim_msg_hdr(g, sim_msg_length_r())    = size + sim_msg_header_size();
308 }
309
310 static inline u32 sim_escape_read_hdr_size(void)
311 {
312         return 12; /*TBD: fix NV_VGPU_SIM_ESCAPE_READ_HEADER*/
313 }
314
315 static u32 *sim_send_ring_bfr(struct gk20a *g, u32 byte_offset)
316 {
317         return (u32 *)(g->sim.send_bfr.kvaddr + byte_offset);
318 }
319
320 static int rpc_send_message(struct gk20a *g)
321 {
322         /* calculations done in units of u32s */
323         u32 send_base = sim_send_put_pointer_v(g->sim.send_ring_put) * 2;
324         u32 dma_offset = send_base + sim_dma_r()/sizeof(u32);
325         u32 dma_hi_offset = send_base + sim_dma_hi_r()/sizeof(u32);
326
327         *sim_send_ring_bfr(g, dma_offset*sizeof(u32)) =
328                 sim_dma_target_phys_pci_coherent_f() |
329                 sim_dma_status_valid_f() |
330                 sim_dma_size_4kb_f() |
331                 sim_dma_addr_lo_f(g->sim.msg_bfr.phys >> PAGE_SHIFT);
332
333         *sim_send_ring_bfr(g, dma_hi_offset*sizeof(u32)) = 0; /*TBD >32b phys*/
334
335         *sim_msg_hdr(g, sim_msg_sequence_r()) = g->sim.sequence_base++;
336
337         g->sim.send_ring_put = (g->sim.send_ring_put + 2 * sizeof(u32)) %
338                 PAGE_SIZE;
339
340         __cpuc_flush_dcache_area(g->sim.msg_bfr.kvaddr, PAGE_SIZE);
341         __cpuc_flush_dcache_area(g->sim.send_bfr.kvaddr, PAGE_SIZE);
342         __cpuc_flush_dcache_area(g->sim.recv_bfr.kvaddr, PAGE_SIZE);
343
344         /* Update the put pointer. This will trap into the host. */
345         sim_writel(g, sim_send_put_r(), g->sim.send_ring_put);
346
347         return 0;
348 }
349
350 static inline u32 *sim_recv_ring_bfr(struct gk20a *g, u32 byte_offset)
351 {
352         return (u32 *)(g->sim.recv_bfr.kvaddr + byte_offset);
353 }
354
355 static int rpc_recv_poll(struct gk20a *g)
356 {
357         phys_addr_t recv_phys_addr;
358
359         /* XXX This read is not required (?) */
360         /*pVGpu->recv_ring_get = VGPU_REG_RD32(pGpu, NV_VGPU_RECV_GET);*/
361
362         /* Poll the recv ring get pointer in an infinite loop*/
363         do {
364                 g->sim.recv_ring_put = sim_readl(g, sim_recv_put_r());
365         } while (g->sim.recv_ring_put == g->sim.recv_ring_get);
366
367         /* process all replies */
368         while (g->sim.recv_ring_put != g->sim.recv_ring_get) {
369                 /* these are in u32 offsets*/
370                 u32 dma_lo_offset =
371                         sim_recv_put_pointer_v(g->sim.recv_ring_get)*2 + 0;
372                 /*u32 dma_hi_offset = dma_lo_offset + 1;*/
373                 u32 recv_phys_addr_lo = sim_dma_addr_lo_v(*sim_recv_ring_bfr(g, dma_lo_offset*4));
374
375                 /*u32 recv_phys_addr_hi = sim_dma_hi_addr_v(
376                       (phys_addr_t)sim_recv_ring_bfr(g,dma_hi_offset*4));*/
377
378                 /*TBD >32b phys addr */
379                 recv_phys_addr = recv_phys_addr_lo << PAGE_SHIFT;
380
381                 if (recv_phys_addr != g->sim.msg_bfr.phys) {
382                         dev_err(dev_from_gk20a(g), "%s Error in RPC reply\n",
383                                 __func__);
384                         return -1;
385                 }
386
387                 /* Update GET pointer */
388                 g->sim.recv_ring_get = (g->sim.recv_ring_get + 2*sizeof(u32)) %
389                         PAGE_SIZE;
390
391                 __cpuc_flush_dcache_area(g->sim.msg_bfr.kvaddr, PAGE_SIZE);
392                 __cpuc_flush_dcache_area(g->sim.send_bfr.kvaddr, PAGE_SIZE);
393                 __cpuc_flush_dcache_area(g->sim.recv_bfr.kvaddr, PAGE_SIZE);
394
395                 sim_writel(g, sim_recv_get_r(), g->sim.recv_ring_get);
396
397                 g->sim.recv_ring_put = sim_readl(g, sim_recv_put_r());
398         }
399
400         return 0;
401 }
402
403 static int issue_rpc_and_wait(struct gk20a *g)
404 {
405         int err;
406
407         err = rpc_send_message(g);
408         if (err) {
409                 dev_err(dev_from_gk20a(g), "%s failed rpc_send_message\n",
410                         __func__);
411                 return err;
412         }
413
414         err = rpc_recv_poll(g);
415         if (err) {
416                 dev_err(dev_from_gk20a(g), "%s failed rpc_recv_poll\n",
417                         __func__);
418                 return err;
419         }
420
421         /* Now check if RPC really succeeded */
422         if (*sim_msg_hdr(g, sim_msg_result_r()) != sim_msg_result_success_v()) {
423                 dev_err(dev_from_gk20a(g), "%s received failed status!\n",
424                         __func__);
425                 return -(*sim_msg_hdr(g, sim_msg_result_r()));
426         }
427         return 0;
428 }
429
430 int gk20a_sim_esc_read(struct gk20a *g, char *path, u32 index, u32 count, u32 *data)
431 {
432         int err;
433         size_t pathlen = strlen(path);
434         u32 data_offset;
435
436         sim_write_hdr(g, sim_msg_function_sim_escape_read_v(),
437                       sim_escape_read_hdr_size());
438         *sim_msg_param(g, 0) = index;
439         *sim_msg_param(g, 4) = count;
440         data_offset = roundup(0xc +  pathlen + 1, sizeof(u32));
441         *sim_msg_param(g, 8) = data_offset;
442         strcpy((char *)sim_msg_param(g, 0xc), path);
443
444         err = issue_rpc_and_wait(g);
445
446         if (!err)
447                 memcpy(data, sim_msg_param(g, data_offset), count);
448         return err;
449 }
450
451 static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id)
452 {
453         struct gk20a *g = dev_id;
454         u32 mc_intr_0;
455
456         if (!g->power_on)
457                 return IRQ_NONE;
458
459         /* not from gpu when sharing irq with others */
460         mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
461         if (unlikely(!mc_intr_0))
462                 return IRQ_NONE;
463
464         gk20a_writel(g, mc_intr_en_0_r(),
465                 mc_intr_en_0_inta_disabled_f());
466
467         /* flush previous write */
468         gk20a_readl(g, mc_intr_en_0_r());
469
470         return IRQ_WAKE_THREAD;
471 }
472
473 static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id)
474 {
475         struct gk20a *g = dev_id;
476         u32 mc_intr_1;
477
478         if (!g->power_on)
479                 return IRQ_NONE;
480
481         /* not from gpu when sharing irq with others */
482         mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
483         if (unlikely(!mc_intr_1))
484                 return IRQ_NONE;
485
486         gk20a_writel(g, mc_intr_en_1_r(),
487                 mc_intr_en_1_inta_disabled_f());
488
489         /* flush previous write */
490         gk20a_readl(g, mc_intr_en_1_r());
491
492         return IRQ_WAKE_THREAD;
493 }
494
495 static void gk20a_pbus_isr(struct gk20a *g)
496 {
497         u32 val;
498         val = gk20a_readl(g, bus_intr_0_r());
499         if (val & (bus_intr_0_pri_squash_m() |
500                         bus_intr_0_pri_fecserr_m() |
501                         bus_intr_0_pri_timeout_m())) {
502                 nvhost_err(dev_from_gk20a(g), "top_fs_status_r : 0x%x",
503                         gk20a_readl(g, top_fs_status_r()));
504                 nvhost_err(dev_from_gk20a(g), "pmc_enable : 0x%x",
505                         gk20a_readl(g, mc_enable_r()));
506                 nvhost_err(&g->dev->dev,
507                         "NV_PTIMER_PRI_TIMEOUT_SAVE_0: 0x%x\n",
508                         gk20a_readl(g, timer_pri_timeout_save_0_r()));
509                 nvhost_err(&g->dev->dev,
510                         "NV_PTIMER_PRI_TIMEOUT_SAVE_1: 0x%x\n",
511                         gk20a_readl(g, timer_pri_timeout_save_1_r()));
512                 nvhost_err(&g->dev->dev,
513                         "NV_PTIMER_PRI_TIMEOUT_FECS_ERRCODE: 0x%x\n",
514                         gk20a_readl(g, timer_pri_timeout_fecs_errcode_r()));
515         }
516
517         if (val)
518                 nvhost_err(&g->dev->dev,
519                         "Unhandled pending pbus interrupt\n");
520
521         gk20a_writel(g, bus_intr_0_r(), val);
522 }
523
524 static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id)
525 {
526         struct gk20a *g = dev_id;
527         u32 mc_intr_0;
528
529         nvhost_dbg(dbg_intr, "interrupt thread launched");
530
531         mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
532
533         nvhost_dbg(dbg_intr, "stall intr %08x\n", mc_intr_0);
534
535         if (mc_intr_0 & mc_intr_0_pgraph_pending_f())
536                 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
537         if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
538                 gk20a_fifo_isr(g);
539         if (mc_intr_0 & mc_intr_0_pmu_pending_f())
540                 gk20a_pmu_isr(g);
541         if (mc_intr_0 & mc_intr_0_priv_ring_pending_f())
542                 gk20a_priv_ring_isr(g);
543         if (mc_intr_0 & mc_intr_0_ltc_pending_f())
544                 gk20a_mm_ltc_isr(g);
545         if (mc_intr_0 & mc_intr_0_pbus_pending_f())
546                 gk20a_pbus_isr(g);
547
548         gk20a_writel(g, mc_intr_en_0_r(),
549                 mc_intr_en_0_inta_hardware_f());
550
551         /* flush previous write */
552         gk20a_readl(g, mc_intr_en_0_r());
553
554         return IRQ_HANDLED;
555 }
556
557 static irqreturn_t gk20a_intr_thread_nonstall(int irq, void *dev_id)
558 {
559         struct gk20a *g = dev_id;
560         u32 mc_intr_1;
561
562         nvhost_dbg(dbg_intr, "interrupt thread launched");
563
564         mc_intr_1 = gk20a_readl(g, mc_intr_1_r());
565
566         nvhost_dbg(dbg_intr, "non-stall intr %08x\n", mc_intr_1);
567
568         if (mc_intr_1 & mc_intr_0_pfifo_pending_f())
569                 gk20a_fifo_nonstall_isr(g);
570         if (mc_intr_1 & mc_intr_0_pgraph_pending_f())
571                 gk20a_gr_nonstall_isr(g);
572
573         gk20a_writel(g, mc_intr_en_1_r(),
574                 mc_intr_en_1_inta_hardware_f());
575
576         /* flush previous write */
577         gk20a_readl(g, mc_intr_en_1_r());
578
579         return IRQ_HANDLED;
580 }
581
582 static void gk20a_remove_support(struct platform_device *dev)
583 {
584         struct gk20a *g = get_gk20a(dev);
585
586         /* pmu support should already be removed when driver turns off
587            gpu power rail in prepapre_poweroff */
588         if (g->gk20a_cdev.gk20a_cooling_dev)
589                 thermal_cooling_device_unregister(g->gk20a_cdev.gk20a_cooling_dev);
590
591         if (g->gr.remove_support)
592                 g->gr.remove_support(&g->gr);
593
594         if (g->fifo.remove_support)
595                 g->fifo.remove_support(&g->fifo);
596
597         if (g->mm.remove_support)
598                 g->mm.remove_support(&g->mm);
599
600         if (g->sim.remove_support)
601                 g->sim.remove_support(&g->sim);
602
603         release_firmware(g->pmu_fw);
604
605         if (g->irq_requested) {
606                 free_irq(gk20a_intr.start, g);
607                 free_irq(gk20a_intr.start+1, g);
608                 g->irq_requested = false;
609         }
610
611         /* free mappings to registers, etc*/
612
613         if (g->regs) {
614                 iounmap(g->regs);
615                 g->regs = 0;
616         }
617 }
618
619 int nvhost_init_gk20a_support(struct platform_device *dev)
620 {
621         int err = 0;
622         struct gk20a *g = get_gk20a(dev);
623         struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
624
625         g->regs = pdata->aperture[GK20A_BAR0_IORESOURCE_MEM];
626         if (!g->regs) {
627                 dev_err(dev_from_gk20a(g), "failed to remap gk20a registers\n");
628                 err = -ENXIO;
629                 goto fail;
630         }
631
632         g->bar1 = pdata->aperture[GK20A_BAR1_IORESOURCE_MEM];
633         if (!g->bar1) {
634                 dev_err(dev_from_gk20a(g), "failed to remap gk20a bar1\n");
635                 err = -ENXIO;
636                 goto fail;
637         }
638
639         if (tegra_cpu_is_asim()) {
640                 err = gk20a_init_sim_support(dev);
641                 if (err)
642                         goto fail;
643         }
644
645         mutex_init(&g->dbg_sessions_lock);
646
647         /* nvhost_as alloc_share can be called before gk20a is powered on.
648            It requires mm sw states configured so init mm sw early here. */
649         err = gk20a_init_mm_setup_sw(g);
650         if (err)
651                 goto fail;
652
653         /* other inits are deferred until gpu is powered up. */
654
655         g->remove_support = gk20a_remove_support;
656         return 0;
657
658  fail:
659         gk20a_remove_support(dev);
660         return err;
661 }
662
663 int nvhost_gk20a_init(struct platform_device *dev)
664 {
665         nvhost_dbg_fn("");
666
667 #ifndef CONFIG_PM_RUNTIME
668         nvhost_gk20a_finalize_poweron(dev);
669 #endif
670
671         if (IS_ENABLED(CONFIG_GK20A_DEVFREQ))
672                 nvhost_gk20a_scale_hw_init(dev);
673         return 0;
674 }
675
676 void nvhost_gk20a_deinit(struct platform_device *dev)
677 {
678         nvhost_dbg_fn("");
679 #ifndef CONFIG_PM_RUNTIME
680         nvhost_gk20a_prepare_poweroff(dev);
681 #endif
682 }
683
684 static void gk20a_free_hwctx(struct kref *ref)
685 {
686         struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref);
687         nvhost_dbg_fn("");
688
689         gk20a_busy(ctx->channel->dev);
690
691         if (ctx->priv)
692                 gk20a_free_channel(ctx, true);
693
694         gk20a_idle(ctx->channel->dev);
695
696         kfree(ctx);
697 }
698
699 static struct nvhost_hwctx *gk20a_alloc_hwctx(struct nvhost_hwctx_handler *h,
700                                               struct nvhost_channel *ch)
701 {
702         struct nvhost_hwctx *ctx;
703         nvhost_dbg_fn("");
704
705         /* it seems odd to be allocating a channel here but the
706          * t20/t30 notion of a channel is mapped on top of gk20a's
707          * channel.  this works because there is only one module
708          * under gk20a's host (gr).
709          */
710         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
711         if (!ctx)
712                 return NULL;
713
714         kref_init(&ctx->ref);
715         ctx->h = h;
716         ctx->channel = ch;
717
718         return gk20a_open_channel(ch, ctx);
719 }
720
721 static void gk20a_get_hwctx(struct nvhost_hwctx *hwctx)
722 {
723         nvhost_dbg_fn("");
724         kref_get(&hwctx->ref);
725 }
726
727 static void gk20a_put_hwctx(struct nvhost_hwctx *hwctx)
728 {
729         nvhost_dbg_fn("");
730         kref_put(&hwctx->ref, gk20a_free_hwctx);
731 }
732
733 static void gk20a_save_push_hwctx(struct nvhost_hwctx *ctx, struct nvhost_cdma *cdma)
734 {
735         nvhost_dbg_fn("");
736 }
737
738 struct nvhost_hwctx_handler *
739     nvhost_gk20a_alloc_hwctx_handler(u32 syncpt, u32 waitbase,
740                                      struct nvhost_channel *ch)
741 {
742
743         struct nvhost_hwctx_handler *h;
744         nvhost_dbg_fn("");
745
746         h = kmalloc(sizeof(*h), GFP_KERNEL);
747         if (!h)
748                 return NULL;
749
750         h->alloc = gk20a_alloc_hwctx;
751         h->get   = gk20a_get_hwctx;
752         h->put   = gk20a_put_hwctx;
753         h->save_push = gk20a_save_push_hwctx;
754
755         return h;
756 }
757
758 int nvhost_gk20a_prepare_poweroff(struct platform_device *dev)
759 {
760         struct gk20a *g = get_gk20a(dev);
761         int ret = 0;
762
763         nvhost_dbg_fn("");
764
765         if (!g->power_on)
766                 return 0;
767
768         ret |= gk20a_channel_suspend(g);
769
770         /* disable elpg before gr or fifo suspend */
771         ret |= gk20a_pmu_destroy(g);
772         ret |= gk20a_gr_suspend(g);
773         ret |= gk20a_mm_suspend(g);
774         ret |= gk20a_fifo_suspend(g);
775
776         /*
777          * After this point, gk20a interrupts should not get
778          * serviced.
779          */
780         if (g->irq_requested) {
781                 free_irq(gk20a_intr.start, g);
782                 free_irq(gk20a_intr.start+1, g);
783                 g->irq_requested = false;
784         }
785
786         /* Disable GPCPLL */
787         ret |= gk20a_suspend_clk_support(g);
788         g->power_on = false;
789
790         return ret;
791 }
792
793 int nvhost_gk20a_finalize_poweron(struct platform_device *dev)
794 {
795         struct gk20a *g = get_gk20a(dev);
796         int err, nice_value;
797
798         nvhost_dbg_fn("");
799
800         if (g->power_on)
801                 return 0;
802
803         nice_value = task_nice(current);
804         set_user_nice(current, -20);
805
806         if (!g->irq_requested) {
807                 err = request_threaded_irq(gk20a_intr.start,
808                                 gk20a_intr_isr_stall,
809                                 gk20a_intr_thread_stall,
810                                 0, "gk20a_stall", g);
811                 if (err) {
812                         dev_err(dev_from_gk20a(g),
813                                 "failed to request stall intr irq @ %lld\n",
814                                         (u64)gk20a_intr.start);
815                         goto done;
816                 }
817                 err = request_threaded_irq(gk20a_intr.start+1,
818                                 gk20a_intr_isr_nonstall,
819                                 gk20a_intr_thread_nonstall,
820                                 0, "gk20a_nonstall", g);
821                 if (err) {
822                         dev_err(dev_from_gk20a(g),
823                                 "failed to request non-stall intr irq @ %lld\n",
824                                         (u64)gk20a_intr.start+1);
825                         goto done;
826                 }
827                 g->irq_requested = true;
828         }
829
830         g->power_on = true;
831
832         gk20a_writel(g, mc_intr_mask_1_r(),
833                         mc_intr_0_pfifo_pending_f()
834                         | mc_intr_0_pgraph_pending_f());
835         gk20a_writel(g, mc_intr_en_1_r(),
836                 mc_intr_en_1_inta_hardware_f());
837
838         gk20a_writel(g, mc_intr_mask_0_r(),
839                         mc_intr_0_pgraph_pending_f()
840                         | mc_intr_0_pfifo_pending_f()
841                         | mc_intr_0_pmu_pending_f()
842                         | mc_intr_0_priv_ring_pending_f()
843                         | mc_intr_0_ltc_pending_f()
844                         | mc_intr_0_pbus_pending_f());
845         gk20a_writel(g, mc_intr_en_0_r(),
846                 mc_intr_en_0_inta_hardware_f());
847
848         gk20a_writel(g, bus_intr_en_0_r(),
849                         bus_intr_en_0_pri_squash_m() |
850                         bus_intr_en_0_pri_fecserr_m() |
851                         bus_intr_en_0_pri_timeout_m());
852         gk20a_reset_priv_ring(g);
853
854         /* TBD: move this after graphics init in which blcg/slcg is enabled.
855            This function removes SlowdownOnBoot which applies 32x divider
856            on gpcpll bypass path. The purpose of slowdown is to save power
857            during boot but it also significantly slows down gk20a init on
858            simulation and emulation. We should remove SOB after graphics power
859            saving features (blcg/slcg) are enabled. For now, do it here. */
860         err = gk20a_init_clk_support(g);
861         if (err) {
862                 nvhost_err(&dev->dev, "failed to init gk20a clk");
863                 goto done;
864         }
865
866         err = gk20a_init_fifo_reset_enable_hw(g);
867         if (err) {
868                 nvhost_err(&dev->dev, "failed to reset gk20a fifo");
869                 goto done;
870         }
871
872         err = gk20a_init_mm_support(g);
873         if (err) {
874                 nvhost_err(&dev->dev, "failed to init gk20a mm");
875                 goto done;
876         }
877
878         err = gk20a_init_pmu_support(g);
879         if (err) {
880                 nvhost_err(&dev->dev, "failed to init gk20a pmu");
881                 goto done;
882         }
883
884         err = gk20a_init_fifo_support(g);
885         if (err) {
886                 nvhost_err(&dev->dev, "failed to init gk20a fifo");
887                 goto done;
888         }
889
890         err = gk20a_init_gr_support(g);
891         if (err) {
892                 nvhost_err(&dev->dev, "failed to init gk20a gr");
893                 goto done;
894         }
895
896         err = gk20a_init_pmu_setup_hw2(g);
897         if (err) {
898                 nvhost_err(&dev->dev, "failed to init gk20a pmu_hw2");
899                 goto done;
900         }
901
902         err = gk20a_init_therm_support(g);
903         if (err) {
904                 nvhost_err(&dev->dev, "failed to init gk20a therm");
905                 goto done;
906         }
907
908         err = gk20a_init_gpu_characteristics(g);
909         if (err) {
910                 nvhost_err(&dev->dev, "failed to init gk20a gpu characteristics");
911                 goto done;
912         }
913
914         gk20a_channel_resume(g);
915         set_user_nice(current, nice_value);
916
917 done:
918         return err;
919 }
920
921 static struct of_device_id tegra_gk20a_of_match[] = {
922         { .compatible = "nvidia,tegra124-gk20a",
923                 .data = (struct nvhost_device_data *)&tegra_gk20a_info },
924         { },
925 };
926
927 int tegra_gpu_get_max_state(struct thermal_cooling_device *cdev,
928                 unsigned long *max_state)
929 {
930         struct cooling_device_gk20a *gk20a_gpufreq_device = cdev->devdata;
931
932         *max_state = gk20a_gpufreq_device->gk20a_freq_table_size - 1;
933         return 0;
934 }
935
936 int tegra_gpu_get_cur_state(struct thermal_cooling_device *cdev,
937                 unsigned long *cur_state)
938 {
939         struct cooling_device_gk20a  *gk20a_gpufreq_device = cdev->devdata;
940
941         *cur_state = gk20a_gpufreq_device->gk20a_freq_state;
942         return 0;
943 }
944
945 int tegra_gpu_set_cur_state(struct thermal_cooling_device *c_dev,
946                 unsigned long cur_state)
947 {
948         u32 target_freq;
949         struct gk20a *g;
950         struct gpufreq_table_data *gpu_cooling_table;
951         struct cooling_device_gk20a *gk20a_gpufreq_device = c_dev->devdata;
952
953         BUG_ON(cur_state >= gk20a_gpufreq_device->gk20a_freq_table_size);
954
955         g = container_of(gk20a_gpufreq_device, struct gk20a, gk20a_cdev);
956
957         gpu_cooling_table = tegra_gpufreq_table_get();
958         target_freq = gpu_cooling_table[cur_state].frequency;
959
960         /* ensure a query for state will get the proper value */
961         gk20a_gpufreq_device->gk20a_freq_state = cur_state;
962
963         gk20a_clk_set_rate(g, target_freq);
964
965         return 0;
966 }
967
968 static struct thermal_cooling_device_ops tegra_gpu_cooling_ops = {
969         .get_max_state = tegra_gpu_get_max_state,
970         .get_cur_state = tegra_gpu_get_cur_state,
971         .set_cur_state = tegra_gpu_set_cur_state,
972 };
973
974 static int gk20a_suspend_notifier(struct notifier_block *notifier,
975                                   unsigned long pm_event, void *unused)
976 {
977         struct gk20a *g = container_of(notifier, struct gk20a,
978                                        system_suspend_notifier);
979
980         if (pm_event == PM_USERSPACE_FROZEN)
981                 return g->power_on ? NOTIFY_BAD : NOTIFY_OK;
982
983         return NOTIFY_DONE;
984 }
985
986 static int gk20a_probe(struct platform_device *dev)
987 {
988         struct gk20a *gk20a;
989         int err;
990         struct nvhost_device_data *pdata = NULL;
991         struct cooling_device_gk20a *gpu_cdev = NULL;
992
993         if (dev->dev.of_node) {
994                 const struct of_device_id *match;
995
996                 match = of_match_device(tegra_gk20a_of_match, &dev->dev);
997                 if (match)
998                         pdata = (struct nvhost_device_data *)match->data;
999         } else
1000                 pdata = (struct nvhost_device_data *)dev->dev.platform_data;
1001
1002         if (!pdata) {
1003                 dev_err(&dev->dev, "no platform data\n");
1004                 return -ENODATA;
1005         }
1006
1007         nvhost_dbg_fn("");
1008         pdata->pdev = dev;
1009         mutex_init(&pdata->lock);
1010         platform_set_drvdata(dev, pdata);
1011
1012         err = nvhost_client_device_get_resources(dev);
1013         if (err)
1014                 return err;
1015
1016         nvhost_module_init(dev);
1017
1018         gk20a = kzalloc(sizeof(struct gk20a), GFP_KERNEL);
1019         if (!gk20a) {
1020                 dev_err(&dev->dev, "couldn't allocate gk20a support");
1021                 return -ENOMEM;
1022         }
1023
1024         set_gk20a(dev, gk20a);
1025         gk20a->dev = dev;
1026         gk20a->host = nvhost_get_host(dev);
1027
1028         nvhost_init_gk20a_support(dev);
1029
1030 #ifdef CONFIG_PM_GENERIC_DOMAINS
1031         pdata->pd.name = "gk20a";
1032
1033         err = nvhost_module_add_domain(&pdata->pd, dev);
1034 #endif
1035
1036         if (pdata->can_powergate) {
1037                 gk20a->system_suspend_notifier.notifier_call =
1038                         gk20a_suspend_notifier;
1039                 register_pm_notifier(&gk20a->system_suspend_notifier);
1040         }
1041
1042         err = nvhost_client_device_init(dev);
1043         if (err) {
1044                 nvhost_dbg_fn("failed to init client device for %s",
1045                               dev->name);
1046                 pm_runtime_put(&dev->dev);
1047                 return err;
1048         }
1049
1050         err = nvhost_as_init_device(dev);
1051         if (err) {
1052                 nvhost_dbg_fn("failed to init client address space"
1053                               " device for %s", dev->name);
1054                 return err;
1055         }
1056
1057         gpu_cdev = &gk20a->gk20a_cdev;
1058         gpu_cdev->gk20a_freq_table_size = tegra_gpufreq_table_size_get();
1059         gpu_cdev->gk20a_freq_state = 0;
1060         gpu_cdev->g = gk20a;
1061         gpu_cdev->gk20a_cooling_dev = thermal_cooling_device_register("gk20a_cdev", gpu_cdev,
1062                                         &tegra_gpu_cooling_ops);
1063
1064         gk20a->gr_idle_timeout_default =
1065                         CONFIG_GK20A_DEFAULT_TIMEOUT;
1066         gk20a->timeouts_enabled = true;
1067
1068         /* Set up initial clock gating settings */
1069         if (tegra_platform_is_silicon()) {
1070                 gk20a->slcg_enabled = true;
1071                 gk20a->blcg_enabled = true;
1072                 gk20a->elcg_enabled = true;
1073                 gk20a->elpg_enabled = true;
1074         }
1075
1076         gk20a_create_sysfs(dev);
1077
1078 #ifdef CONFIG_DEBUG_FS
1079         clk_gk20a_debugfs_init(dev);
1080
1081         spin_lock_init(&gk20a->debugfs_lock);
1082         gk20a->mm.ltc_enabled = true;
1083         gk20a->mm.ltc_enabled_debug = true;
1084         gk20a->debugfs_ltc_enabled =
1085                         debugfs_create_bool("ltc_enabled", S_IRUGO|S_IWUSR,
1086                                  pdata->debugfs,
1087                                  &gk20a->mm.ltc_enabled_debug);
1088         gk20a->mm.ltc_enabled_debug = true;
1089         gk20a->debugfs_gr_idle_timeout_default =
1090                         debugfs_create_u32("gr_idle_timeout_default_us",
1091                                         S_IRUGO|S_IWUSR, pdata->debugfs,
1092                                          &gk20a->gr_idle_timeout_default);
1093         gk20a->debugfs_timeouts_enabled =
1094                         debugfs_create_bool("timeouts_enabled",
1095                                         S_IRUGO|S_IWUSR,
1096                                         pdata->debugfs,
1097                                         &gk20a->timeouts_enabled);
1098         gk20a_pmu_debugfs_init(dev);
1099 #endif
1100
1101 #ifdef CONFIG_INPUT_CFBOOST
1102         cfb_add_device(&dev->dev);
1103 #endif
1104
1105         return 0;
1106 }
1107
1108 static int __exit gk20a_remove(struct platform_device *dev)
1109 {
1110         struct gk20a *g = get_gk20a(dev);
1111         nvhost_dbg_fn("");
1112
1113 #ifdef CONFIG_INPUT_CFBOOST
1114         cfb_remove_device(&dev->dev);
1115 #endif
1116
1117         if (g->remove_support)
1118                 g->remove_support(dev);
1119
1120         set_gk20a(dev, 0);
1121 #ifdef CONFIG_DEBUG_FS
1122         debugfs_remove(g->debugfs_ltc_enabled);
1123         debugfs_remove(g->debugfs_gr_idle_timeout_default);
1124         debugfs_remove(g->debugfs_timeouts_enabled);
1125 #endif
1126
1127         kfree(g);
1128
1129 #ifdef CONFIG_PM_RUNTIME
1130         pm_runtime_put(&dev->dev);
1131         pm_runtime_disable(&dev->dev);
1132 #else
1133         nvhost_module_disable_clk(&dev->dev);
1134 #endif
1135
1136         return 0;
1137 }
1138
1139 static struct platform_driver gk20a_driver = {
1140         .probe = gk20a_probe,
1141         .remove = __exit_p(gk20a_remove),
1142         .driver = {
1143                 .owner = THIS_MODULE,
1144                 .name = "gk20a",
1145 #ifdef CONFIG_OF
1146                 .of_match_table = tegra_gk20a_of_match,
1147 #endif
1148 #ifdef CONFIG_PM
1149                 .pm = &nvhost_module_pm_ops,
1150 #endif
1151         }
1152 };
1153
1154 static int __init gk20a_init(void)
1155 {
1156                 if (tegra_cpu_is_asim()) {
1157                         tegra_gk20a_device.resource = gk20a_resources_sim;
1158                         tegra_gk20a_device.num_resources = 3;
1159                 }
1160         return platform_driver_register(&gk20a_driver);
1161 }
1162
1163 static void __exit gk20a_exit(void)
1164 {
1165         platform_driver_unregister(&gk20a_driver);
1166 }
1167
1168 void gk20a_busy(struct platform_device *pdev)
1169 {
1170         struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
1171         pm_runtime_get_sync(&pdev->dev);
1172         if (pdata->busy)
1173                 pdata->busy(pdev);
1174 }
1175
1176 void gk20a_idle(struct platform_device *pdev)
1177 {
1178         struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
1179 #ifdef CONFIG_PM_RUNTIME
1180         if (pdata->busy && atomic_read(&pdev->dev.power.usage_count) == 1)
1181                 pdata->idle(pdev);
1182         pm_runtime_mark_last_busy(&pdev->dev);
1183         pm_runtime_put_sync_autosuspend(&pdev->dev);
1184 #else
1185         if (pdata->idle)
1186                 pdata->idle(dev);
1187 #endif
1188 }
1189
1190 void gk20a_disable(struct gk20a *g, u32 units)
1191 {
1192         u32 pmc;
1193
1194         nvhost_dbg(dbg_info, "pmc disable: %08x\n", units);
1195
1196         spin_lock(&g->mc_enable_lock);
1197         pmc = gk20a_readl(g, mc_enable_r());
1198         pmc &= ~units;
1199         gk20a_writel(g, mc_enable_r(), pmc);
1200         spin_unlock(&g->mc_enable_lock);
1201 }
1202
1203 void gk20a_enable(struct gk20a *g, u32 units)
1204 {
1205         u32 pmc;
1206
1207         nvhost_dbg(dbg_info, "pmc enable: %08x\n", units);
1208
1209         spin_lock(&g->mc_enable_lock);
1210         pmc = gk20a_readl(g, mc_enable_r());
1211         pmc |= units;
1212         gk20a_writel(g, mc_enable_r(), pmc);
1213         spin_unlock(&g->mc_enable_lock);
1214         gk20a_readl(g, mc_enable_r());
1215
1216         udelay(20);
1217 }
1218
1219 void gk20a_reset(struct gk20a *g, u32 units)
1220 {
1221         gk20a_disable(g, units);
1222         udelay(20);
1223         gk20a_enable(g, units);
1224 }
1225
1226 static u32 gk20a_determine_L2_size_bytes(struct gk20a *g)
1227 {
1228         const u32 gpuid = GK20A_GPUID(g->gpu_characteristics.arch,
1229                                       g->gpu_characteristics.impl);
1230         u32 lts_per_ltc;
1231         u32 ways;
1232         u32 sets;
1233         u32 bytes_per_line;
1234         u32 active_ltcs;
1235         u32 cache_size;
1236
1237         u32 tmp;
1238         u32 active_sets_value;
1239
1240         tmp = gk20a_readl(g, ltc_ltc0_lts0_tstg_cfg1_r());
1241         ways = hweight32(ltc_ltc0_lts0_tstg_cfg1_active_ways_v(tmp));
1242
1243         active_sets_value = ltc_ltc0_lts0_tstg_cfg1_active_sets_v(tmp);
1244         if (active_sets_value == ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v()) {
1245                 sets = 64;
1246         } else if (active_sets_value ==
1247                  ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v()) {
1248                 sets = 32;
1249         } else if (active_sets_value ==
1250                  ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v()) {
1251                 sets = 16;
1252         } else {
1253                 dev_err(dev_from_gk20a(g),
1254                         "Unknown constant %u for active sets",
1255                        (unsigned)active_sets_value);
1256                 sets = 0;
1257         }
1258
1259         active_ltcs = g->gr.num_fbps;
1260
1261         /* chip-specific values */
1262         switch (gpuid) {
1263         case GK20A_GPUID_GK20A:
1264                 lts_per_ltc = 1;
1265                 bytes_per_line = 128;
1266                 break;
1267
1268         default:
1269                 dev_err(dev_from_gk20a(g), "Unknown GPU id 0x%02x\n",
1270                         (unsigned)gpuid);
1271                 lts_per_ltc = 0;
1272                 bytes_per_line = 0;
1273         }
1274
1275         cache_size = active_ltcs * lts_per_ltc * ways * sets * bytes_per_line;
1276
1277         return cache_size;
1278 }
1279
1280 int gk20a_init_gpu_characteristics(struct gk20a *g)
1281 {
1282         struct nvhost_gpu_characteristics *gpu = &g->gpu_characteristics;
1283
1284         u32 mc_boot_0_value;
1285         mc_boot_0_value = gk20a_readl(g, mc_boot_0_r());
1286         gpu->arch = mc_boot_0_architecture_v(mc_boot_0_value) <<
1287                 NVHOST_GPU_ARCHITECTURE_SHIFT;
1288         gpu->impl = mc_boot_0_implementation_v(mc_boot_0_value);
1289         gpu->rev =
1290                 (mc_boot_0_major_revision_v(mc_boot_0_value) << 4) |
1291                 mc_boot_0_minor_revision_v(mc_boot_0_value);
1292
1293         gpu->L2_cache_size = gk20a_determine_L2_size_bytes(g);
1294         gpu->on_board_video_memory_size = 0; /* integrated GPU */
1295
1296         gpu->num_gpc = g->gr.gpc_count;
1297         gpu->num_tpc_per_gpc = g->gr.max_tpc_per_gpc_count;
1298
1299         gpu->bus_type = NVHOST_GPU_BUS_TYPE_AXI; /* always AXI for now */
1300
1301         return 0;
1302 }
1303
1304 module_init(gk20a_init);
1305 module_exit(gk20a_exit);