blob: 9ad407b25f4e9f0079ba0584128292687dd75d09 [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>
15#include <linux/platform_device.h>
16#include <linux/io.h>
17#include <linux/err.h>
18
19#include "qdss.h"
20
21#define funnel_writel(funnel, id, val, off) \
22 __raw_writel((val), funnel.base + (SZ_4K * id) + off)
23#define funnel_readl(funnel, id, off) \
24 __raw_readl(funnel.base + (SZ_4K * id) + off)
25
26#define CS_TFUNNEL_FUNCTL (0x000)
27#define CS_TFUNNEL_PRICTL (0x004)
28#define CS_TFUNNEL_ITATBDATA0 (0xEEC)
29#define CS_TFUNNEL_ITATBCTR2 (0xEF0)
30#define CS_TFUNNEL_ITATBCTR1 (0xEF4)
31#define CS_TFUNNEL_ITATBCTR0 (0xEF8)
32
33
34#define FUNNEL_LOCK(id) \
35do { \
36 mb(); \
37 funnel_writel(funnel, id, MAGIC2, CS_LAR); \
38} while (0)
39#define FUNNEL_UNLOCK(id) \
40do { \
41 funnel_writel(funnel, id, MAGIC1, CS_LAR); \
42 mb(); \
43} while (0)
44
45#define DEFAULT_HOLDTIME_MASK (0xF00)
46#define DEFAULT_HOLDTIME_SHFT (0x8)
47#define DEFAULT_HOLDTIME (0x7 << DEFAULT_HOLDTIME_SHFT)
48#define DEFAULT_PRIORITY (0xFAC680)
49
50struct funnel_ctx {
51 void __iomem *base;
52 bool enabled;
53 struct device *dev;
54};
55
56static struct funnel_ctx funnel;
57
58static void __funnel_enable(uint8_t id, uint32_t port_mask)
59{
60 uint32_t functl;
61
62 FUNNEL_UNLOCK(id);
63
64 functl = funnel_readl(funnel, id, CS_TFUNNEL_FUNCTL);
65 functl &= ~DEFAULT_HOLDTIME_MASK;
66 functl |= DEFAULT_HOLDTIME;
67 functl |= port_mask;
68 funnel_writel(funnel, id, functl, CS_TFUNNEL_FUNCTL);
69 funnel_writel(funnel, id, DEFAULT_PRIORITY, CS_TFUNNEL_PRICTL);
70
71 FUNNEL_LOCK(id);
72}
73
74void funnel_enable(uint8_t id, uint32_t port_mask)
75{
76 __funnel_enable(id, port_mask);
77 funnel.enabled = true;
78 dev_info(funnel.dev, "funnel port mask 0x%lx enabled\n",
79 (unsigned long) port_mask);
80}
81
82static void __funnel_disable(uint8_t id, uint32_t port_mask)
83{
84 uint32_t functl;
85
86 FUNNEL_UNLOCK(id);
87
88 functl = funnel_readl(funnel, id, CS_TFUNNEL_FUNCTL);
89 functl &= ~port_mask;
90 funnel_writel(funnel, id, functl, CS_TFUNNEL_FUNCTL);
91
92 FUNNEL_LOCK(id);
93}
94
95void funnel_disable(uint8_t id, uint32_t port_mask)
96{
97 __funnel_disable(id, port_mask);
98 funnel.enabled = false;
99 dev_info(funnel.dev, "funnel port mask 0x%lx disabled\n",
100 (unsigned long) port_mask);
101}
102
103static int __devinit funnel_probe(struct platform_device *pdev)
104{
105 int ret;
106 struct resource *res;
107
108 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
109 if (!res) {
110 ret = -EINVAL;
111 goto err_res;
112 }
113
114 funnel.base = ioremap_nocache(res->start, resource_size(res));
115 if (!funnel.base) {
116 ret = -EINVAL;
117 goto err_ioremap;
118 }
119
120 funnel.dev = &pdev->dev;
121
122 return 0;
123
124err_ioremap:
125err_res:
126 return ret;
127}
128
129static int __devexit funnel_remove(struct platform_device *pdev)
130{
131 if (funnel.enabled)
132 funnel_disable(0x0, 0xFF);
133 iounmap(funnel.base);
134
135 return 0;
136}
137
138static struct platform_driver funnel_driver = {
139 .probe = funnel_probe,
140 .remove = __devexit_p(funnel_remove),
141 .driver = {
142 .name = "msm_funnel",
143 },
144};
145
146static int __init funnel_init(void)
147{
148 return platform_driver_register(&funnel_driver);
149}
150module_init(funnel_init);
151
152static void __exit funnel_exit(void)
153{
154 platform_driver_unregister(&funnel_driver);
155}
156module_exit(funnel_exit);
157
158MODULE_LICENSE("GPL v2");
159MODULE_DESCRIPTION("Coresight Funnel");