]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/video/tegra/host/host1x/host1x_tickctrl.c
video: tegra: host: use platform bus/driver/device
[linux-3.10.git] / drivers / video / tegra / host / host1x / host1x_tickctrl.c
1 /*
2  * drivers/video/tegra/host/host1x/host1x_counter.c
3  *
4  * Tegra Graphics Host Counter support
5  *
6  * Copyright (c) 2012, 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/nvhost.h>
22 #include <linux/io.h>
23 #include "dev.h"
24 #include "chip_support.h"
25
26 static int host1x_tickctrl_init_host(struct nvhost_master *host)
27 {
28         void __iomem *regs = host->aperture;
29
30         /* Initialize counter */
31         writel(0, regs + host1x_channel_tickcount_hi_r());
32         writel(0, regs + host1x_channel_tickcount_lo_r());
33
34         writel(host1x_channel_channelctrl_enabletickcnt_f(1),
35                         regs + host1x_channel_channelctrl_r());
36
37         return 0;
38 }
39
40 static void host1x_tickctrl_deinit_host(struct nvhost_master *host)
41 {
42         void __iomem *regs = host->aperture;
43
44         writel(host1x_channel_channelctrl_enabletickcnt_f(0),
45                         regs + host1x_channel_channelctrl_r());
46 }
47
48 static int host1x_tickctrl_init_channel(struct platform_device *dev)
49 {
50         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
51         void __iomem *regs = pdata->channel->aperture;
52
53         /* Initialize counter */
54         writel(0, regs + host1x_channel_stallcount_hi_r());
55         writel(0, regs + host1x_channel_stallcount_lo_r());
56         writel(0, regs + host1x_channel_xfercount_hi_r());
57         writel(0, regs + host1x_channel_xfercount_lo_r());
58
59         writel(host1x_channel_stallctrl_enable_channel_stall_f(1),
60                         regs + host1x_channel_stallctrl_r());
61         writel(host1x_channel_xferctrl_enable_channel_xfer_f(1),
62                         regs + host1x_channel_xferctrl_r());
63
64         return 0;
65 }
66
67 static void host1x_tickctrl_deinit_channel(struct platform_device *dev)
68 {
69         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
70         void __iomem *regs = pdata->channel->aperture;
71
72         writel(host1x_channel_stallctrl_enable_channel_stall_f(0),
73                         regs + host1x_channel_stallctrl_r());
74         writel(host1x_channel_xferctrl_enable_channel_xfer_f(0),
75                         regs + host1x_channel_xferctrl_r());
76 }
77
78 static u64 readl64(void __iomem *reg_hi, void __iomem *reg_lo)
79 {
80         u32 hi, lo, hi2;
81         do {
82                 hi = readl(reg_hi);
83                 lo = readl(reg_lo);
84                 hi2 = readl(reg_hi);
85         } while (hi2 != hi);
86         return ((u64)hi << 32) | (u64)lo;
87 }
88
89 static int host1x_tickctrl_tickcount(struct platform_device *dev, u64 *val)
90 {
91         void __iomem *regs = nvhost_get_host(dev)->aperture;
92
93         *val = readl64(regs + host1x_channel_tickcount_hi_r(),
94                 regs + host1x_channel_tickcount_lo_r());
95         rmb();
96
97         return 0;
98 }
99
100 static int host1x_tickctrl_stallcount(struct platform_device *dev, u64 *val)
101 {
102         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
103         void __iomem *regs = pdata->channel->aperture;
104
105         *val = readl64(regs + host1x_channel_stallcount_hi_r(),
106                 regs + host1x_channel_stallcount_lo_r());
107         rmb();
108
109         return 0;
110 }
111
112 static int host1x_tickctrl_xfercount(struct platform_device *dev, u64 *val)
113 {
114         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
115         void __iomem *regs = pdata->channel->aperture;
116
117         *val = readl64(regs + host1x_channel_xfercount_hi_r(),
118                 regs + host1x_channel_xfercount_lo_r());
119         rmb();
120
121         return 0;
122 }
123
124 static const struct nvhost_tickctrl_ops host1x_tickctrl_ops = {
125         .init_host = host1x_tickctrl_init_host,
126         .deinit_host = host1x_tickctrl_deinit_host,
127         .init_channel = host1x_tickctrl_init_channel,
128         .deinit_channel = host1x_tickctrl_deinit_channel,
129         .tickcount = host1x_tickctrl_tickcount,
130         .stallcount = host1x_tickctrl_stallcount,
131         .xfercount = host1x_tickctrl_xfercount,
132 };