blob: 290b418544b2ab6b1f08fc4bd75dbc53d1673155 [file] [log] [blame]
Pratik Patel7831c082011-06-08 21:44:37 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
Pratik Patelcf418622011-09-22 11:15:11 -070015#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/device.h>
Pratik Patel7831c082011-06-08 21:44:37 -070018#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/err.h>
21
22#include "qdss.h"
23
24#define funnel_writel(funnel, id, val, off) \
25 __raw_writel((val), funnel.base + (SZ_4K * id) + off)
26#define funnel_readl(funnel, id, off) \
27 __raw_readl(funnel.base + (SZ_4K * id) + off)
28
29#define CS_TFUNNEL_FUNCTL (0x000)
30#define CS_TFUNNEL_PRICTL (0x004)
31#define CS_TFUNNEL_ITATBDATA0 (0xEEC)
32#define CS_TFUNNEL_ITATBCTR2 (0xEF0)
33#define CS_TFUNNEL_ITATBCTR1 (0xEF4)
34#define CS_TFUNNEL_ITATBCTR0 (0xEF8)
35
36
37#define FUNNEL_LOCK(id) \
38do { \
39 mb(); \
40 funnel_writel(funnel, id, MAGIC2, CS_LAR); \
41} while (0)
42#define FUNNEL_UNLOCK(id) \
43do { \
44 funnel_writel(funnel, id, MAGIC1, CS_LAR); \
45 mb(); \
46} while (0)
47
48#define DEFAULT_HOLDTIME_MASK (0xF00)
49#define DEFAULT_HOLDTIME_SHFT (0x8)
50#define DEFAULT_HOLDTIME (0x7 << DEFAULT_HOLDTIME_SHFT)
51#define DEFAULT_PRIORITY (0xFAC680)
52
53struct funnel_ctx {
54 void __iomem *base;
55 bool enabled;
56 struct device *dev;
57};
58
59static struct funnel_ctx funnel;
60
61static void __funnel_enable(uint8_t id, uint32_t port_mask)
62{
63 uint32_t functl;
64
65 FUNNEL_UNLOCK(id);
66
67 functl = funnel_readl(funnel, id, CS_TFUNNEL_FUNCTL);
68 functl &= ~DEFAULT_HOLDTIME_MASK;
69 functl |= DEFAULT_HOLDTIME;
70 functl |= port_mask;
71 funnel_writel(funnel, id, functl, CS_TFUNNEL_FUNCTL);
72 funnel_writel(funnel, id, DEFAULT_PRIORITY, CS_TFUNNEL_PRICTL);
73
74 FUNNEL_LOCK(id);
75}
76
77void funnel_enable(uint8_t id, uint32_t port_mask)
78{
79 __funnel_enable(id, port_mask);
80 funnel.enabled = true;
81 dev_info(funnel.dev, "funnel port mask 0x%lx enabled\n",
82 (unsigned long) port_mask);
83}
84
85static void __funnel_disable(uint8_t id, uint32_t port_mask)
86{
87 uint32_t functl;
88
89 FUNNEL_UNLOCK(id);
90
91 functl = funnel_readl(funnel, id, CS_TFUNNEL_FUNCTL);
92 functl &= ~port_mask;
93 funnel_writel(funnel, id, functl, CS_TFUNNEL_FUNCTL);
94
95 FUNNEL_LOCK(id);
96}
97
98void funnel_disable(uint8_t id, uint32_t port_mask)
99{
100 __funnel_disable(id, port_mask);
101 funnel.enabled = false;
102 dev_info(funnel.dev, "funnel port mask 0x%lx disabled\n",
103 (unsigned long) port_mask);
104}
105
106static int __devinit funnel_probe(struct platform_device *pdev)
107{
108 int ret;
109 struct resource *res;
110
111 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
112 if (!res) {
113 ret = -EINVAL;
114 goto err_res;
115 }
116
117 funnel.base = ioremap_nocache(res->start, resource_size(res));
118 if (!funnel.base) {
119 ret = -EINVAL;
120 goto err_ioremap;
121 }
122
123 funnel.dev = &pdev->dev;
124
125 return 0;
126
127err_ioremap:
128err_res:
129 return ret;
130}
131
132static int __devexit funnel_remove(struct platform_device *pdev)
133{
134 if (funnel.enabled)
135 funnel_disable(0x0, 0xFF);
136 iounmap(funnel.base);
137
138 return 0;
139}
140
141static struct platform_driver funnel_driver = {
142 .probe = funnel_probe,
143 .remove = __devexit_p(funnel_remove),
144 .driver = {
145 .name = "msm_funnel",
146 },
147};
148
149static int __init funnel_init(void)
150{
151 return platform_driver_register(&funnel_driver);
152}
153module_init(funnel_init);
154
155static void __exit funnel_exit(void)
156{
157 platform_driver_unregister(&funnel_driver);
158}
159module_exit(funnel_exit);
160
161MODULE_LICENSE("GPL v2");
162MODULE_DESCRIPTION("Coresight Funnel");