2 * Support functions for OMAP3 SDTI (Serial Debug Tracing Interface)
4 * Copyright (C) 2008 Nokia Corporation
5 * Written by: Roman Tereshonkov <roman.tereshonkov@nokia.com>
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
11 #include <linux/init.h>
12 #include <linux/err.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/spinlock.h>
16 #include <linux/interrupt.h>
17 #include <linux/platform_device.h>
18 #include <linux/clk.h>
20 #include <asm/byteorder.h>
23 #define SDTI_REVISION 0x000
24 #define SDTI_SYSCONFIG 0x010
25 #define SDTI_SYSSTATUS 0x014
26 #define SDTI_WINCTRL 0x024
27 #define SDTI_SCONFIG 0x028
28 #define SDTI_TESTCTRL 0x02C
29 #define SDTI_LOCK_ACCESS 0xFB0
31 #define CPU1_TRACE_EN 0x01
32 #define CPU2_TRACE_EN 0x02
34 #define SDTI_SYSCONFIG_SOFTRESET (1 << 1)
35 #define SDTI_SYSCONFIG_AUTOIDLE (1 << 0)
37 static struct clk *sdti_fck, *sdti_ick;
38 void __iomem *sti_base, *sti_channel_base;
39 static DEFINE_SPINLOCK(sdti_lock);
40 static int sdti_initialized;
42 void sti_channel_write_trace(int len, int id, void *data,
45 const u8 *tpntr = data;
48 spin_lock_irqsave(&sdti_lock, flags);
50 if (unlikely(!sdti_initialized))
53 sti_channel_writeb(id, channel);
55 sti_channel_writeb(*tpntr++, channel);
56 sti_channel_flush(channel);
58 spin_unlock_irqrestore(&sdti_lock, flags);
60 EXPORT_SYMBOL(sti_channel_write_trace);
62 static void omap_sdti_reset(void)
66 sti_writel(SDTI_SYSCONFIG_SOFTRESET, SDTI_SYSCONFIG);
68 for (i = 0; i < 10000; i++)
69 if (sti_readl(SDTI_SYSSTATUS) & 1)
72 printk(KERN_WARNING "XTI: no real reset\n");
75 static int __init omap_sdti_init(void)
80 sdti_fck = clk_get(NULL, "pclk_fck");
81 if (IS_ERR(sdti_fck)) {
82 printk(KERN_ERR "Cannot get clk pclk_fck\n");
83 ret = PTR_ERR(sdti_fck);
86 sdti_ick = clk_get(NULL, "pclkx2_fck");
87 if (IS_ERR(sdti_ick)) {
88 printk(KERN_ERR "Cannot get clk pclkx2_fck\n");
89 ret = PTR_ERR(sdti_ick);
92 ret = clk_enable(sdti_fck);
94 printk(KERN_ERR "Cannot enable sdti_fck\n");
97 ret = clk_enable(sdti_ick);
99 printk(KERN_ERR "Cannot enable sdti_ick\n");
104 sti_writel(0xC5ACCE55, SDTI_LOCK_ACCESS);
107 sti_writel(SDTI_SYSCONFIG_AUTOIDLE, SDTI_SYSCONFIG);
110 sti_writel(1 << 30, SDTI_WINCTRL);
111 i = sti_readl(SDTI_WINCTRL);
112 if (!(i & (1 << 30)))
113 printk(KERN_WARNING "SDTI: cannot claim SDTI\n");
115 /* 4 bits dual, fclk/3 */
116 sti_writel(0x43, SDTI_SCONFIG);
118 /* CPU2 trace enable */
119 sti_writel(i | CPU2_TRACE_EN, SDTI_WINCTRL);
120 i = sti_readl(SDTI_WINCTRL);
123 sti_writel((1 << 31) | (i & 0x3FFFFFFF), SDTI_WINCTRL);
125 spin_lock_irq(&sdti_lock);
126 sdti_initialized = 1;
127 spin_unlock_irq(&sdti_lock);
129 i = sti_readl(SDTI_REVISION);
130 snprintf(buf, sizeof(buf), "OMAP SDTI support loaded (HW v%u.%u)\n",
131 (i >> 4) & 0x0f, i & 0x0f);
132 printk(KERN_INFO "%s", buf);
133 sti_channel_write_trace(strlen(buf), 0xc3, buf, 239);
138 clk_disable(sdti_fck);
147 static void omap_sdti_exit(void)
149 sti_writel(0, SDTI_WINCTRL);
150 clk_disable(sdti_fck);
151 clk_disable(sdti_ick);
156 static int __devinit omap_sdti_probe(struct platform_device *pdev)
158 struct resource *res, *cres;
161 if (pdev->num_resources != 2) {
162 dev_err(&pdev->dev, "invalid number of resources: %d\n",
163 pdev->num_resources);
168 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
169 if (unlikely(!res)) {
170 dev_err(&pdev->dev, "invalid mem resource\n");
175 cres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
176 if (unlikely(!cres)) {
177 dev_err(&pdev->dev, "invalid channel mem resource\n");
181 size = res->end - res->start;
182 sti_base = ioremap(res->start, size);
183 if (unlikely(!sti_base))
186 size = cres->end - cres->start;
187 sti_channel_base = ioremap(cres->start, size);
188 if (unlikely(!sti_channel_base)) {
193 return omap_sdti_init();
196 static int __devexit omap_sdti_remove(struct platform_device *pdev)
198 iounmap(sti_channel_base);
205 static struct platform_driver omap_sdti_driver = {
206 .probe = omap_sdti_probe,
207 .remove = __devexit_p(omap_sdti_remove),
210 .owner = THIS_MODULE,
214 static int __init omap_sdti_module_init(void)
216 return platform_driver_register(&omap_sdti_driver);
219 static void __exit omap_sdti_module_exit(void)
221 platform_driver_unregister(&omap_sdti_driver);
223 subsys_initcall(omap_sdti_module_init);
224 module_exit(omap_sdti_module_exit);
226 MODULE_AUTHOR("Roman Tereshonkov");
227 MODULE_LICENSE("GPL");