fccb1fe014bc549910ec7591a8c477afca93ec6f
[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-2013, NVIDIA Corporation.
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
32 #include <asm/cacheflush.h>
33
34 #include <mach/powergate.h>
35 #include <mach/pm_domains.h>
36
37 #include "dev.h"
38 #include "class_ids.h"
39 #include "bus_client.h"
40 #include "nvhost_as.h"
41
42 #include "gk20a.h"
43 #include "ctrl_gk20a.h"
44 #include "hw_mc_gk20a.h"
45 #include "hw_sim_gk20a.h"
46 #include "gk20a_scale.h"
47 #include "gr3d/pod_scaling.h"
48
49 #include "../../../../../../arch/arm/mach-tegra/iomap.h"
50
51 static inline void set_gk20a(struct platform_device *dev, struct gk20a *gk20a)
52 {
53         nvhost_set_private_data(dev, gk20a);
54 }
55
56 static void nvhost_gk20a_deinit(struct platform_device *dev);
57 static struct nvhost_hwctx_handler *
58     nvhost_gk20a_alloc_hwctx_handler(u32 syncpt, u32 base,
59                                      struct nvhost_channel *ch);
60
61 /* TBD: should be able to put in the list below. */
62 static struct resource gk20a_intr = {
63         .start = TEGRA_GK20A_INTR,
64         .end   = TEGRA_GK20A_INTR_NONSTALL,
65         .flags = IORESOURCE_IRQ,
66 };
67
68 struct resource gk20a_resources[] = {
69 #define GK20A_BAR0_IORESOURCE_MEM 0
70 {
71         .start = TEGRA_GK20A_BAR0_BASE,
72         .end   = TEGRA_GK20A_BAR0_BASE + TEGRA_GK20A_BAR0_SIZE - 1,
73         .flags = IORESOURCE_MEM,
74 },
75 #define GK20A_BAR1_IORESOURCE_MEM 1
76 {
77         .start = TEGRA_GK20A_BAR1_BASE,
78         .end   = TEGRA_GK20A_BAR1_BASE + TEGRA_GK20A_BAR1_SIZE - 1,
79         .flags = IORESOURCE_MEM,
80 },
81 #if CONFIG_GK20A_SIM
82 #define GK20A_SIM_IORESOURCE_MEM 2
83 {
84 #define TEGRA_GK20A_SIM_BASE 0x538F0000 /*tbd: get from iomap.h should get this or replacement */
85 #define TEGRA_GK20A_SIM_SIZE 0x1000     /*tbd: this is a high-side guess */
86         .start = TEGRA_GK20A_SIM_BASE,
87         .end   = TEGRA_GK20A_SIM_BASE + TEGRA_GK20A_SIM_SIZE - 1,
88         .flags = IORESOURCE_MEM,
89 },
90 #endif
91 };
92
93 static const struct file_operations gk20a_ctrl_ops = {
94         .owner = THIS_MODULE,
95         .release = gk20a_ctrl_dev_release,
96         .open = gk20a_ctrl_dev_open,
97         .unlocked_ioctl = gk20a_ctrl_dev_ioctl,
98 };
99
100 static struct nvhost_device_data tegra_gk20a_info = {
101         /* the following are set by the platform (e.g. t124) support
102         .syncpts       = BIT(NVSYNCPT_3D),
103         .waitbases     = BIT(NVWAITBASE_3D),
104         .modulemutexes = BIT(NVMODMUTEX_3D),
105         */
106         .class         = NV_GRAPHICS_GPU_CLASS_ID,
107         .clocks = {{"PLLG_ref", UINT_MAX}, {"pwr", UINT_MAX}, \
108                    {"emc", UINT_MAX}, {} },
109         .powergate_ids = { TEGRA_POWERGATE_GPU, -1 },
110         NVHOST_DEFAULT_CLOCKGATE_DELAY,
111         .powergate_delay = 500,
112         .can_powergate = false,
113         .alloc_hwctx_handler = nvhost_gk20a_alloc_hwctx_handler,
114         .ctrl_ops = &gk20a_ctrl_ops,
115         .moduleid      = NVHOST_MODULE_GPU,
116 };
117
118 struct platform_device tegra_gk20a_device = {
119         .name          = "gk20a",
120         .resource      = gk20a_resources,
121 #if CONFIG_GK20A_SIM
122         .num_resources = 3, /* this is num ioresource_mem, not the sum */
123 #else
124         .num_resources = 2, /* this is num ioresource_mem, not the sum */
125 #endif
126         .dev           = {
127                 .platform_data = &tegra_gk20a_info,
128         },
129 };
130
131
132
133 #if CONFIG_GK20A_SIM
134 static inline void sim_writel(struct gk20a *g, u32 r, u32 v)
135 {
136         writel(v, g->sim.regs+r);
137 }
138 static inline u32 sim_readl(struct gk20a *g, u32 r)
139 {
140         return readl(g->sim.regs+r);
141 }
142
143 static void kunmap_and_free_iopage(void **kvaddr, struct page **page)
144 {
145         if (*kvaddr) {
146                 kunmap(*kvaddr);
147                 *kvaddr = 0;
148         }
149         if (*page) {
150                 __free_page(*page);
151                 *page = 0;
152         }
153 }
154
155 static void gk20a_free_sim_support(struct gk20a *g)
156 {
157         /* free sim mappings, bfrs */
158         kunmap_and_free_iopage(&g->sim.send_bfr.kvaddr,
159                                &g->sim.send_bfr.page);
160
161         kunmap_and_free_iopage(&g->sim.recv_bfr.kvaddr,
162                                &g->sim.recv_bfr.page);
163
164         kunmap_and_free_iopage(&g->sim.msg_bfr.kvaddr,
165                                &g->sim.msg_bfr.page);
166 }
167
168 static void gk20a_remove_sim_support(struct sim_gk20a *s)
169 {
170         struct gk20a *g = s->g;
171         if (g->sim.regs)
172                 sim_writel(g, sim_config_r(), sim_config_mode_disabled_v());
173         gk20a_free_sim_support(g);
174 }
175
176 static int alloc_and_kmap_iopage(struct device *d,
177                                  void **kvaddr,
178                                  phys_addr_t *phys,
179                                  struct page **page)
180 {
181         int err = 0;
182         *page = alloc_page(GFP_KERNEL);
183
184         if (!*page) {
185                 err = -ENOMEM;
186                 dev_err(d, "couldn't allocate io page\n");
187                 goto fail;
188         }
189
190         *kvaddr = kmap(*page);
191         if (!*kvaddr) {
192                 err = -ENOMEM;
193                 dev_err(d, "couldn't kmap io page\n");
194                 goto fail;
195         }
196         *phys = page_to_phys(*page);
197         return 0;
198
199  fail:
200         kunmap_and_free_iopage(kvaddr, page);
201         return err;
202
203 }
204 /* TBD: strip from released */
205 static int gk20a_init_sim_support(struct platform_device *dev)
206 {
207         int err = 0;
208         struct gk20a *g = get_gk20a(dev);
209         struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
210         struct device *d = &dev->dev;
211         phys_addr_t phys;
212
213         g->sim.g = g;
214         g->sim.regs = pdata->aperture[GK20A_SIM_IORESOURCE_MEM];
215         if (!g->sim.regs) {
216                 dev_err(d, "failed to remap gk20a sim regs\n");
217                 err = -ENXIO;
218                 goto fail;
219         }
220
221         /* allocate sim event/msg buffers */
222         err = alloc_and_kmap_iopage(d, &g->sim.send_bfr.kvaddr,
223                                     &g->sim.send_bfr.phys,
224                                     &g->sim.send_bfr.page);
225
226         err = err || alloc_and_kmap_iopage(d, &g->sim.recv_bfr.kvaddr,
227                                            &g->sim.recv_bfr.phys,
228                                            &g->sim.recv_bfr.page);
229
230         err = err || alloc_and_kmap_iopage(d, &g->sim.msg_bfr.kvaddr,
231                                            &g->sim.msg_bfr.phys,
232                                            &g->sim.msg_bfr.page);
233
234         if (!(g->sim.send_bfr.kvaddr && g->sim.recv_bfr.kvaddr &&
235               g->sim.msg_bfr.kvaddr)) {
236                 dev_err(d, "couldn't allocate all sim buffers\n");
237                 goto fail;
238         }
239
240         /*mark send ring invalid*/
241         sim_writel(g, sim_send_ring_r(), sim_send_ring_status_invalid_f());
242
243         /*read get pointer and make equal to put*/
244         g->sim.send_ring_put = sim_readl(g, sim_send_get_r());
245         sim_writel(g, sim_send_put_r(), g->sim.send_ring_put);
246
247         /*write send ring address and make it valid*/
248         /*TBD: work for >32b physmem*/
249         phys = g->sim.send_bfr.phys;
250         sim_writel(g, sim_send_ring_hi_r(), 0);
251         sim_writel(g, sim_send_ring_r(),
252                    sim_send_ring_status_valid_f() |
253                    sim_send_ring_target_phys_pci_coherent_f() |
254                    sim_send_ring_size_4kb_f() |
255                    sim_send_ring_addr_lo_f(phys >> PAGE_SHIFT));
256
257         /*repeat for recv ring (but swap put,get as roles are opposite) */
258         sim_writel(g, sim_recv_ring_r(), sim_recv_ring_status_invalid_f());
259
260         /*read put pointer and make equal to get*/
261         g->sim.recv_ring_get = sim_readl(g, sim_recv_put_r());
262         sim_writel(g, sim_recv_get_r(), g->sim.recv_ring_get);
263
264         /*write send ring address and make it valid*/
265         /*TBD: work for >32b physmem*/
266         phys = g->sim.recv_bfr.phys;
267         sim_writel(g, sim_recv_ring_hi_r(), 0);
268         sim_writel(g, sim_recv_ring_r(),
269                    sim_recv_ring_status_valid_f() |
270                    sim_recv_ring_target_phys_pci_coherent_f() |
271                    sim_recv_ring_size_4kb_f() |
272                    sim_recv_ring_addr_lo_f(phys >> PAGE_SHIFT));
273
274         g->sim.remove_support = gk20a_remove_sim_support;
275         return 0;
276
277  fail:
278         gk20a_free_sim_support(g);
279         return err;
280 }
281
282 static inline u32 sim_msg_header_size(void)
283 {
284         return 24;/*TBD: fix the header to gt this from NV_VGPU_MSG_HEADER*/
285 }
286
287 static inline u32 *sim_msg_bfr(struct gk20a *g, u32 byte_offset)
288 {
289         return (u32 *)(g->sim.msg_bfr.kvaddr + byte_offset);
290 }
291
292 static inline u32 *sim_msg_hdr(struct gk20a *g, u32 byte_offset)
293 {
294         return sim_msg_bfr(g, byte_offset); /*starts at 0*/
295 }
296
297 static inline u32 *sim_msg_param(struct gk20a *g, u32 byte_offset)
298 {
299         /*starts after msg header/cmn*/
300         return sim_msg_bfr(g, byte_offset + sim_msg_header_size());
301 }
302
303 static inline void sim_write_hdr(struct gk20a *g, u32 func, u32 size)
304 {
305         /*memset(g->sim.msg_bfr.kvaddr,0,min(PAGE_SIZE,size));*/
306         *sim_msg_hdr(g, sim_msg_signature_r()) = sim_msg_signature_valid_v();
307         *sim_msg_hdr(g, sim_msg_result_r())    = sim_msg_result_rpc_pending_v();
308         *sim_msg_hdr(g, sim_msg_spare_r())     = sim_msg_spare__init_v();
309         *sim_msg_hdr(g, sim_msg_function_r())  = func;
310         *sim_msg_hdr(g, sim_msg_length_r())    = size + sim_msg_header_size();
311 }
312
313 static inline u32 sim_escape_read_hdr_size(void)
314 {
315         return 12; /*TBD: fix NV_VGPU_SIM_ESCAPE_READ_HEADER*/
316 }
317 static u32 *sim_send_ring_bfr(struct gk20a *g, u32 byte_offset)
318 {
319         return (u32 *)(g->sim.send_bfr.kvaddr + byte_offset);
320 }
321 static int rpc_send_message(struct gk20a *g)
322 {
323         /* calculations done in units of u32s */
324         u32 send_base = sim_send_put_pointer_v(g->sim.send_ring_put) * 2;
325         u32 dma_offset = send_base + sim_dma_r()/sizeof(u32);
326         u32 dma_hi_offset = send_base + sim_dma_hi_r()/sizeof(u32);
327
328         *sim_send_ring_bfr(g, dma_offset*sizeof(u32)) =
329                 sim_dma_target_phys_pci_coherent_f() |
330                 sim_dma_status_valid_f() |
331                 sim_dma_size_4kb_f() |
332                 sim_dma_addr_lo_f(g->sim.msg_bfr.phys >> PAGE_SHIFT);
333
334         *sim_send_ring_bfr(g, dma_hi_offset*sizeof(u32)) = 0; /*TBD >32b phys*/
335
336         *sim_msg_hdr(g, sim_msg_sequence_r()) = g->sim.sequence_base++;
337
338         g->sim.send_ring_put = (g->sim.send_ring_put + 2 * sizeof(u32)) %
339                 PAGE_SIZE;
340
341         __cpuc_flush_dcache_area(g->sim.msg_bfr.kvaddr, PAGE_SIZE);
342         __cpuc_flush_dcache_area(g->sim.send_bfr.kvaddr, PAGE_SIZE);
343         __cpuc_flush_dcache_area(g->sim.recv_bfr.kvaddr, PAGE_SIZE);
344
345         /* Update the put pointer. This will trap into the host. */
346         sim_writel(g, sim_send_put_r(), g->sim.send_ring_put);
347
348         return 0;
349 }
350
351 static inline u32 *sim_recv_ring_bfr(struct gk20a *g, u32 byte_offset)
352 {
353         return (u32 *)(g->sim.recv_bfr.kvaddr + byte_offset);
354 }
355
356 static int rpc_recv_poll(struct gk20a *g)
357 {
358         phys_addr_t recv_phys_addr;
359
360         /* XXX This read is not required (?) */
361         /*pVGpu->recv_ring_get = VGPU_REG_RD32(pGpu, NV_VGPU_RECV_GET);*/
362
363         /* Poll the recv ring get pointer in an infinite loop*/
364         do {
365                 g->sim.recv_ring_put = sim_readl(g, sim_recv_put_r());
366         } while (g->sim.recv_ring_put == g->sim.recv_ring_get);
367
368         /* process all replies */
369         while (g->sim.recv_ring_put != g->sim.recv_ring_get) {
370                 /* these are in u32 offsets*/
371                 u32 dma_lo_offset =
372                         sim_recv_put_pointer_v(g->sim.recv_ring_get)*2 + 0;
373                 /*u32 dma_hi_offset = dma_lo_offset + 1;*/
374                 u32 recv_phys_addr_lo = sim_dma_addr_lo_v(*sim_recv_ring_bfr(g, dma_lo_offset*4));
375
376                 /*u32 recv_phys_addr_hi = sim_dma_hi_addr_v(
377                       (phys_addr_t)sim_recv_ring_bfr(g,dma_hi_offset*4));*/
378
379                 /*TBD >32b phys addr */
380                 recv_phys_addr = recv_phys_addr_lo << PAGE_SHIFT;
381
382                 if (recv_phys_addr != g->sim.msg_bfr.phys) {
383                         dev_err(dev_from_gk20a(g), "%s Error in RPC reply\n",
384                                 __func__);
385                         return -1;
386                 }
387
388                 /* Update GET pointer */
389                 g->sim.recv_ring_get = (g->sim.recv_ring_get + 2*sizeof(u32)) %
390                         PAGE_SIZE;
391
392                 __cpuc_flush_dcache_area(g->sim.msg_bfr.kvaddr, PAGE_SIZE);
393                 __cpuc_flush_dcache_area(g->sim.send_bfr.kvaddr, PAGE_SIZE);
394                 __cpuc_flush_dcache_area(g->sim.recv_bfr.kvaddr, PAGE_SIZE);
395
396                 sim_writel(g, sim_recv_get_r(), g->sim.recv_ring_get);
397
398                 g->sim.recv_ring_put = sim_readl(g, sim_recv_put_r());
399         }
400
401         return 0;
402 }
403
404
405 static int issue_rpc_and_wait(struct gk20a *g)
406 {
407         int err;
408
409         err = rpc_send_message(g);
410         if (err) {
411                 dev_err(dev_from_gk20a(g), "%s failed rpc_send_message\n",
412                         __func__);
413                 return err;
414         }
415
416         err = rpc_recv_poll(g);
417         if (err) {
418                 dev_err(dev_from_gk20a(g), "%s failed rpc_recv_poll\n",
419                         __func__);
420                 return err;
421         }
422
423         /* Now check if RPC really succeeded */
424         if (*sim_msg_hdr(g, sim_msg_result_r()) != sim_msg_result_success_v()) {
425                 dev_err(dev_from_gk20a(g), "%s received failed status!\n",
426                         __func__);
427                 return -(*sim_msg_hdr(g, sim_msg_result_r()));
428         }
429         return 0;
430 }
431
432 int gk20a_sim_esc_read(struct gk20a *g, char *path, u32 index, u32 count, u32 *data)
433 {
434         int err;
435         size_t pathlen = strlen(path);
436         u32 data_offset;
437
438         sim_write_hdr(g, sim_msg_function_sim_escape_read_v(),
439                       sim_escape_read_hdr_size());
440         *sim_msg_param(g, 0) = index;
441         *sim_msg_param(g, 4) = count;
442         data_offset = roundup(0xc +  pathlen + 1, sizeof(u32));
443         *sim_msg_param(g, 8) = data_offset;
444         strcpy((char *)sim_msg_param(g, 0xc), path);
445
446         err = issue_rpc_and_wait(g);
447
448         if (!err)
449                 memcpy(data, sim_msg_param(g, data_offset), count);
450         return err;
451 }
452
453
454 #else /*CONFIG_GK20A_SIM*/
455 static inline int gk20a_init_sim_support(struct platform_device *dev)
456 {
457         return 0;
458 }
459 /*static void gk20a_remove_sim_support(struct platform_device *dev)
460 {
461 }*/
462 #endif /*!CONFIG_GK20A_SIM*/
463
464 static irqreturn_t gk20a_intr_isr(int irq, void *dev_id)
465 {
466         struct gk20a *g = dev_id;
467         u32 mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
468
469         /* not from gpu when sharing irq with others */
470         if (unlikely(!mc_intr_0))
471                 return IRQ_NONE;
472
473         gk20a_writel(g, mc_intr_en_0_r(),
474                 mc_intr_en_0_inta_disabled_f());
475
476         /* flush previous write */
477         gk20a_readl(g, mc_intr_en_0_r());
478
479         return IRQ_WAKE_THREAD;
480 }
481
482 static irqreturn_t gk20a_intr_thread(int irq, void *dev_id)
483 {
484         struct gk20a *g = dev_id;
485         u32 mc_intr_0;
486
487         nvhost_dbg(dbg_intr, "interrupt thread launched");
488
489         mc_intr_0 = gk20a_readl(g, mc_intr_0_r());
490
491         if (mc_intr_0 & mc_intr_0_pgraph_pending_f())
492                 gk20a_gr_isr(g);
493         if (mc_intr_0 & mc_intr_0_pfifo_pending_f())
494                 gk20a_fifo_isr(g);
495         if (mc_intr_0 & mc_intr_0_pmu_pending_f())
496                 gk20a_pmu_isr(g);
497         if (mc_intr_0 & mc_intr_0_priv_ring_pending_f())
498                 gk20a_priv_ring_isr(g);
499         if (mc_intr_0)
500                 nvhost_dbg_info("leaving isr with interrupt pending 0x%08x",
501                                 mc_intr_0);
502
503         gk20a_writel(g, mc_intr_en_0_r(),
504                 mc_intr_en_0_inta_hardware_f());
505
506         /* flush previous write */
507         gk20a_readl(g, mc_intr_en_0_r());
508
509         return IRQ_HANDLED;
510 }
511
512 static void gk20a_remove_support(struct platform_device *dev)
513 {
514         struct gk20a *g = get_gk20a(dev);
515
516         /* pmu support should already be removed when driver turns off
517            gpu power rail in prepapre_poweroff */
518
519         if (g->gr.remove_support)
520                 g->gr.remove_support(&g->gr);
521
522         if (g->fifo.remove_support)
523                 g->fifo.remove_support(&g->fifo);
524
525         if (g->mm.remove_support)
526                 g->mm.remove_support(&g->mm);
527
528         if (g->sim.remove_support)
529                 g->sim.remove_support(&g->sim);
530
531         release_firmware(g->pmu_fw);
532
533         if (g->irq_requested) {
534                 free_irq(gk20a_intr.start, g);
535                 g->irq_requested = false;
536         }
537
538         /* free mappings to registers, etc*/
539
540         if (g->regs) {
541                 iounmap(g->regs);
542                 g->regs = 0;
543         }
544 }
545
546 int nvhost_init_gk20a_support(struct platform_device *dev)
547 {
548         int err = 0;
549         struct gk20a *g = get_gk20a(dev);
550         struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
551
552         g->regs = pdata->aperture[GK20A_BAR0_IORESOURCE_MEM];
553         if (!g->regs) {
554                 dev_err(dev_from_gk20a(g), "failed to remap gk20a registers\n");
555                 err = -ENXIO;
556                 goto fail;
557         }
558
559         g->bar1 = pdata->aperture[GK20A_BAR1_IORESOURCE_MEM];
560         if (!g->bar1) {
561                 dev_err(dev_from_gk20a(g), "failed to remap gk20a bar1\n");
562                 err = -ENXIO;
563                 goto fail;
564         }
565
566         err = request_threaded_irq(gk20a_intr.start,
567                         gk20a_intr_isr, gk20a_intr_thread,
568                         0, "gk20a", g);
569         if (err) {
570                 dev_err(dev_from_gk20a(g), "failed to request stall interrupt irq @ %lld\n",
571                         (u64)gk20a_intr.start);
572                 goto fail;
573         }
574         g->irq_requested = true;
575
576         err = gk20a_init_sim_support(dev);
577         if (err)
578                 goto fail;
579
580         /* nvhost_as alloc_share can be called before gk20a is powered on.
581            It requires mm sw states configured so init mm sw early here. */
582         err = gk20a_init_mm_setup_sw(g);
583         if (err)
584                 goto fail;
585
586         /* other inits are deferred until gpu is powered up. */
587
588         g->remove_support = gk20a_remove_support;
589         return 0;
590
591  fail:
592         gk20a_remove_support(dev);
593         return err;
594 }
595
596 int nvhost_gk20a_init(struct platform_device *dev)
597 {
598         nvhost_dbg_fn("");
599         if (IS_ENABLED(CONFIG_TEGRA_GK20A_DEVFREQ))
600                 nvhost_gk20a_scale_hw_init(dev);
601         return 0;
602 }
603
604 static void nvhost_gk20a_deinit(struct platform_device *dev)
605 {
606         nvhost_dbg_fn("");
607 }
608
609 static void gk20a_free_hwctx(struct kref *ref)
610 {
611         struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref);
612         nvhost_dbg_fn("");
613
614         nvhost_module_busy(ctx->channel->dev);
615         if (ctx->priv)
616                 gk20a_free_channel(ctx, true);
617         nvhost_module_idle(ctx->channel->dev);
618
619         kfree(ctx);
620 }
621
622 static struct nvhost_hwctx *gk20a_alloc_hwctx(struct nvhost_hwctx_handler *h,
623                                               struct nvhost_channel *ch)
624 {
625         struct nvhost_hwctx *ctx;
626         nvhost_dbg_fn("");
627
628         /* it seems odd to be allocating a channel here but the
629          * t20/t30 notion of a channel is mapped on top of gk20a's
630          * channel.  this works because there is only one module
631          * under gk20a's host (gr).
632          */
633         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
634         if (!ctx)
635                 return NULL;
636
637         kref_init(&ctx->ref);
638         ctx->h = h;
639         ctx->channel = ch;
640
641         return gk20a_open_channel(ch, ctx);
642 }
643
644 static void gk20a_get_hwctx(struct nvhost_hwctx *hwctx)
645 {
646         nvhost_dbg_fn("");
647         kref_get(&hwctx->ref);
648 }
649
650 static void gk20a_put_hwctx(struct nvhost_hwctx *hwctx)
651 {
652         nvhost_dbg_fn("");
653         kref_put(&hwctx->ref, gk20a_free_hwctx);
654 }
655
656 static void gk20a_save_push_hwctx(struct nvhost_hwctx *ctx, struct nvhost_cdma *cdma)
657 {
658         nvhost_dbg_fn("");
659 }
660
661 static void gk20a_save_service_hwctx(struct nvhost_hwctx *ctx)
662 {
663         nvhost_dbg_fn("");
664 }
665
666 static struct nvhost_hwctx_handler *
667     nvhost_gk20a_alloc_hwctx_handler(u32 syncpt, u32 waitbase,
668                                      struct nvhost_channel *ch)
669 {
670
671         struct nvhost_hwctx_handler *h;
672         nvhost_dbg_fn("");
673
674         h = kmalloc(sizeof(*h), GFP_KERNEL);
675         if (!h)
676                 return NULL;
677
678         h->alloc = gk20a_alloc_hwctx;
679         h->get   = gk20a_get_hwctx;
680         h->put   = gk20a_put_hwctx;
681         h->save_push = gk20a_save_push_hwctx;
682         h->save_service = gk20a_save_service_hwctx;
683
684         return h;
685 }
686
687 int nvhost_gk20a_prepare_poweroff(struct platform_device *dev)
688 {
689         struct gk20a *g = get_gk20a(dev);
690         int ret = 0;
691
692         nvhost_dbg_fn("");
693
694         ret |= gk20a_channel_suspend(g);
695
696         ret |= gk20a_fifo_suspend(g);
697         /* disable elpg before gr suspend */
698         ret |= gk20a_pmu_destroy(g);
699         ret |= gk20a_gr_suspend(g);
700         ret |= gk20a_mm_suspend(g);
701
702         g->power_on = false;
703
704         return ret;
705 }
706
707 int nvhost_gk20a_finalize_poweron(struct platform_device *dev)
708 {
709         struct gk20a *g = get_gk20a(dev);
710         int err;
711
712         nvhost_dbg_fn("");
713
714         if (g->power_on)
715                 return 0;
716
717         g->power_on = true;
718
719         gk20a_writel(g, mc_intr_en_1_r(),
720                 mc_intr_en_1_inta_disabled_f());
721
722         gk20a_writel(g, mc_intr_en_0_r(),
723                 mc_intr_en_0_inta_hardware_f());
724
725         gk20a_reset_priv_ring(g);
726
727         /* TBD: move this after graphics init in which blcg/slcg is enabled.
728            This function removes SlowdownOnBoot which applies 32x divider
729            on gpcpll bypass path. The purpose of slowdown is to save power
730            during boot but it also significantly slows down gk20a init on
731            simulation and emulation. We should remove SOB after graphics power
732            saving features (blcg/slcg) are enabled. For now, do it here. */
733         err = gk20a_init_clk_support(g);
734         if (err)
735                 nvhost_err(&dev->dev, "failed to init gk20a clk");
736
737         err = gk20a_init_mm_support(g);
738         if (err)
739                 nvhost_err(&dev->dev, "failed to init gk20a mm");
740
741         err = gk20a_init_fifo_support(g);
742         if (err)
743                 nvhost_err(&dev->dev, "failed to init gk20a fifo");
744
745         err = gk20a_init_gr_support(g);
746         if (err)
747                 nvhost_err(&dev->dev, "failed to init gk20a gr");
748
749         err = gk20a_init_pmu_support(g);
750         if (err)
751                 nvhost_err(&dev->dev, "failed to init gk20a pmu");
752
753         err = gk20a_init_therm_support(g);
754         if (err)
755                 nvhost_err(&dev->dev, "failed to init gk20a therm");
756
757         gk20a_channel_resume(g);
758
759         return err;
760 }
761
762 static struct of_device_id tegra_gk20a_of_match[] = {
763         { .compatible = "nvidia,tegra124-gk20a",
764                 .data = (struct nvhost_device_data *)&tegra_gk20a_info },
765         { },
766 };
767
768 #ifdef CONFIG_PM_GENERIC_DOMAINS
769 static int gk20a_unpowergate(struct generic_pm_domain *domain)
770 {
771         struct nvhost_device_data *pdata;
772
773         pdata = container_of(domain, struct nvhost_device_data, pd);
774         return nvhost_module_power_on(pdata->pdev);
775 }
776
777 static int gk20a_powergate(struct generic_pm_domain *domain)
778 {
779         struct nvhost_device_data *pdata;
780
781         pdata = container_of(domain, struct nvhost_device_data, pd);
782         return nvhost_module_power_off(pdata->pdev);
783 }
784 #endif
785
786 static int gk20a_probe(struct platform_device *dev)
787 {
788         struct gk20a *gk20a;
789         int err;
790         struct nvhost_device_data *pdata = NULL;
791
792         if (dev->dev.of_node) {
793                 const struct of_device_id *match;
794
795                 match = of_match_device(tegra_gk20a_of_match, &dev->dev);
796                 if (match)
797                         pdata = (struct nvhost_device_data *)match->data;
798         } else
799                 pdata = (struct nvhost_device_data *)dev->dev.platform_data;
800
801         nvhost_dbg_fn("");
802
803         pdata->pdev = dev;
804         mutex_init(&pdata->lock);
805         platform_set_drvdata(dev, pdata);
806         nvhost_module_init(dev);
807
808         pdata->init                     = nvhost_gk20a_init;
809         pdata->deinit                   = nvhost_gk20a_deinit;
810         pdata->alloc_hwctx_handler      = nvhost_gk20a_alloc_hwctx_handler;
811         pdata->prepare_poweroff         = nvhost_gk20a_prepare_poweroff,
812         pdata->finalize_poweron         = nvhost_gk20a_finalize_poweron,
813         pdata->syncpt_base              = 32; /*hack*/
814
815         if (IS_ENABLED(CONFIG_TEGRA_GK20A_DEVFREQ)) {
816                 pdata->busy             = nvhost_gk20a_scale_notify_busy;
817                 pdata->idle             = nvhost_gk20a_scale_notify_idle;
818                 pdata->scaling_init     = nvhost_gk20a_scale_init;
819                 pdata->scaling_deinit   = nvhost_gk20a_scale_deinit;
820                 pdata->suspend_ndev     = nvhost_scale3d_suspend;
821         }
822
823         gk20a = kzalloc(sizeof(struct gk20a), GFP_KERNEL);
824         if (!gk20a) {
825                 dev_err(&dev->dev, "couldn't allocate gk20a support");
826                 return -ENOMEM;
827         }
828
829         set_gk20a(dev, gk20a);
830         gk20a->dev = dev;
831         gk20a->host = nvhost_get_host(dev);
832
833         err = nvhost_client_device_get_resources(dev);
834         if (err)
835                 return err;
836
837         nvhost_init_gk20a_support(dev);
838
839 #ifdef CONFIG_PM_GENERIC_DOMAINS
840         pdata->pd.name = "gk20a";
841         pdata->pd.power_off = gk20a_powergate;
842         pdata->pd.power_on = gk20a_unpowergate;
843         pdata->pd.dev_ops.start = nvhost_module_enable_clk;
844         pdata->pd.dev_ops.stop = nvhost_module_disable_clk;
845
846         err = nvhost_module_add_domain(&pdata->pd, dev);
847
848         /* overwrite save/restore fptrs set by pm_genpd_init */
849         pdata->pd.domain.ops.suspend = nvhost_client_device_suspend;
850         pdata->pd.domain.ops.resume = nvhost_client_device_resume;
851         pdata->pd.dev_ops.restore_state = nvhost_module_finalize_poweron;
852         pdata->pd.dev_ops.save_state = nvhost_module_prepare_poweroff;
853 #endif
854
855         if (pdata->clockgate_delay) {
856                 pm_runtime_set_autosuspend_delay(&dev->dev,
857                         pdata->clockgate_delay);
858                 pm_runtime_use_autosuspend(&dev->dev);
859         }
860         pm_runtime_enable(&dev->dev);
861
862         err = nvhost_client_device_init(dev);
863         if (err) {
864                 nvhost_dbg_fn("failed to init client device for %s",
865                               dev->name);
866                 pm_runtime_put(&dev->dev);
867                 return err;
868         }
869
870         err = nvhost_as_init_device(dev);
871         if (err) {
872                 nvhost_dbg_fn("failed to init client address space"
873                               " device for %s", dev->name);
874                 return err;
875         }
876
877         return 0;
878 }
879
880 static int __exit gk20a_remove(struct platform_device *dev)
881 {
882         struct gk20a *g = get_gk20a(dev);
883         nvhost_dbg_fn("");
884
885         if (g && g->remove_support)
886                 g->remove_support(dev);
887
888         set_gk20a(dev, 0);
889         kfree(g);
890
891         return 0;
892 }
893
894 static struct platform_driver gk20a_driver = {
895         .probe = gk20a_probe,
896         .remove = __exit_p(gk20a_remove),
897         .driver = {
898                 .owner = THIS_MODULE,
899                 .name = "gk20a",
900 #ifdef CONFIG_OF
901                 .of_match_table = tegra_gk20a_of_match,
902 #endif
903         }
904 };
905
906 static int __init gk20a_init(void)
907 {
908         return platform_driver_register(&gk20a_driver);
909 }
910
911 static void __exit gk20a_exit(void)
912 {
913         platform_driver_unregister(&gk20a_driver);
914 }
915
916 module_init(gk20a_init);
917 module_exit(gk20a_exit);