3 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
4 * Copyright (C) 2014 Sebastian Reichel <sre@kernel.org>
6 * Contact: Carlos Chinea <carlos.chinea@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 #include <linux/compiler.h>
24 #include <linux/err.h>
25 #include <linux/ioport.h>
27 #include <linux/gpio.h>
28 #include <linux/clk.h>
29 #include <linux/device.h>
30 #include <linux/platform_device.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/dmaengine.h>
33 #include <linux/delay.h>
34 #include <linux/seq_file.h>
35 #include <linux/scatterlist.h>
36 #include <linux/interrupt.h>
37 #include <linux/spinlock.h>
38 #include <linux/debugfs.h>
39 #include <linux/pm_runtime.h>
40 #include <linux/of_platform.h>
41 #include <linux/hsi/hsi.h>
42 #include <linux/idr.h>
44 #include "omap_ssi_regs.h"
47 /* For automatically allocated device IDs */
48 static DEFINE_IDA(platform_omap_ssi_ida
);
50 #ifdef CONFIG_DEBUG_FS
51 static int ssi_debug_show(struct seq_file
*m
, void *p __maybe_unused
)
53 struct hsi_controller
*ssi
= m
->private;
54 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
55 void __iomem
*sys
= omap_ssi
->sys
;
57 pm_runtime_get_sync(ssi
->device
.parent
);
58 seq_printf(m
, "REVISION\t: 0x%08x\n", readl(sys
+ SSI_REVISION_REG
));
59 seq_printf(m
, "SYSCONFIG\t: 0x%08x\n", readl(sys
+ SSI_SYSCONFIG_REG
));
60 seq_printf(m
, "SYSSTATUS\t: 0x%08x\n", readl(sys
+ SSI_SYSSTATUS_REG
));
61 pm_runtime_put_sync(ssi
->device
.parent
);
66 static int ssi_debug_gdd_show(struct seq_file
*m
, void *p __maybe_unused
)
68 struct hsi_controller
*ssi
= m
->private;
69 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
70 void __iomem
*gdd
= omap_ssi
->gdd
;
71 void __iomem
*sys
= omap_ssi
->sys
;
74 pm_runtime_get_sync(ssi
->device
.parent
);
76 seq_printf(m
, "GDD_MPU_STATUS\t: 0x%08x\n",
77 readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
));
78 seq_printf(m
, "GDD_MPU_ENABLE\t: 0x%08x\n\n",
79 readl(sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
));
80 seq_printf(m
, "HW_ID\t\t: 0x%08x\n",
81 readl(gdd
+ SSI_GDD_HW_ID_REG
));
82 seq_printf(m
, "PPORT_ID\t: 0x%08x\n",
83 readl(gdd
+ SSI_GDD_PPORT_ID_REG
));
84 seq_printf(m
, "MPORT_ID\t: 0x%08x\n",
85 readl(gdd
+ SSI_GDD_MPORT_ID_REG
));
86 seq_printf(m
, "TEST\t\t: 0x%08x\n",
87 readl(gdd
+ SSI_GDD_TEST_REG
));
88 seq_printf(m
, "GCR\t\t: 0x%08x\n",
89 readl(gdd
+ SSI_GDD_GCR_REG
));
91 for (lch
= 0; lch
< SSI_MAX_GDD_LCH
; lch
++) {
92 seq_printf(m
, "\nGDD LCH %d\n=========\n", lch
);
93 seq_printf(m
, "CSDP\t\t: 0x%04x\n",
94 readw(gdd
+ SSI_GDD_CSDP_REG(lch
)));
95 seq_printf(m
, "CCR\t\t: 0x%04x\n",
96 readw(gdd
+ SSI_GDD_CCR_REG(lch
)));
97 seq_printf(m
, "CICR\t\t: 0x%04x\n",
98 readw(gdd
+ SSI_GDD_CICR_REG(lch
)));
99 seq_printf(m
, "CSR\t\t: 0x%04x\n",
100 readw(gdd
+ SSI_GDD_CSR_REG(lch
)));
101 seq_printf(m
, "CSSA\t\t: 0x%08x\n",
102 readl(gdd
+ SSI_GDD_CSSA_REG(lch
)));
103 seq_printf(m
, "CDSA\t\t: 0x%08x\n",
104 readl(gdd
+ SSI_GDD_CDSA_REG(lch
)));
105 seq_printf(m
, "CEN\t\t: 0x%04x\n",
106 readw(gdd
+ SSI_GDD_CEN_REG(lch
)));
107 seq_printf(m
, "CSAC\t\t: 0x%04x\n",
108 readw(gdd
+ SSI_GDD_CSAC_REG(lch
)));
109 seq_printf(m
, "CDAC\t\t: 0x%04x\n",
110 readw(gdd
+ SSI_GDD_CDAC_REG(lch
)));
111 seq_printf(m
, "CLNK_CTRL\t: 0x%04x\n",
112 readw(gdd
+ SSI_GDD_CLNK_CTRL_REG(lch
)));
115 pm_runtime_put_sync(ssi
->device
.parent
);
120 static int ssi_regs_open(struct inode
*inode
, struct file
*file
)
122 return single_open(file
, ssi_debug_show
, inode
->i_private
);
125 static int ssi_gdd_regs_open(struct inode
*inode
, struct file
*file
)
127 return single_open(file
, ssi_debug_gdd_show
, inode
->i_private
);
130 static const struct file_operations ssi_regs_fops
= {
131 .open
= ssi_regs_open
,
134 .release
= single_release
,
137 static const struct file_operations ssi_gdd_regs_fops
= {
138 .open
= ssi_gdd_regs_open
,
141 .release
= single_release
,
144 static int __init
ssi_debug_add_ctrl(struct hsi_controller
*ssi
)
146 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
150 omap_ssi
->dir
= debugfs_create_dir(dev_name(&ssi
->device
), NULL
);
154 debugfs_create_file("regs", S_IRUGO
, omap_ssi
->dir
, ssi
,
157 dir
= debugfs_create_dir("gdd", omap_ssi
->dir
);
160 debugfs_create_file("regs", S_IRUGO
, dir
, ssi
, &ssi_gdd_regs_fops
);
164 debugfs_remove_recursive(omap_ssi
->dir
);
169 static void ssi_debug_remove_ctrl(struct hsi_controller
*ssi
)
171 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
173 debugfs_remove_recursive(omap_ssi
->dir
);
175 #endif /* CONFIG_DEBUG_FS */
178 * FIXME: Horrible HACK needed until we remove the useless wakeline test
179 * in the CMT. To be removed !!!!
181 void ssi_waketest(struct hsi_client
*cl
, unsigned int enable
)
183 struct hsi_port
*port
= hsi_get_port(cl
);
184 struct omap_ssi_port
*omap_port
= hsi_port_drvdata(port
);
185 struct hsi_controller
*ssi
= to_hsi_controller(port
->device
.parent
);
186 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
188 omap_port
->wktest
= !!enable
;
189 if (omap_port
->wktest
) {
190 pm_runtime_get_sync(ssi
->device
.parent
);
191 writel_relaxed(SSI_WAKE(0),
192 omap_ssi
->sys
+ SSI_SET_WAKE_REG(port
->num
));
194 writel_relaxed(SSI_WAKE(0),
195 omap_ssi
->sys
+ SSI_CLEAR_WAKE_REG(port
->num
));
196 pm_runtime_put_sync(ssi
->device
.parent
);
199 EXPORT_SYMBOL_GPL(ssi_waketest
);
201 static void ssi_gdd_complete(struct hsi_controller
*ssi
, unsigned int lch
)
203 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
204 struct hsi_msg
*msg
= omap_ssi
->gdd_trn
[lch
].msg
;
205 struct hsi_port
*port
= to_hsi_port(msg
->cl
->device
.parent
);
206 struct omap_ssi_port
*omap_port
= hsi_port_drvdata(port
);
211 spin_lock(&omap_ssi
->lock
);
213 val
= readl(omap_ssi
->sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
);
214 val
&= ~SSI_GDD_LCH(lch
);
215 writel_relaxed(val
, omap_ssi
->sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
);
217 if (msg
->ttype
== HSI_MSG_READ
) {
218 dir
= DMA_FROM_DEVICE
;
219 val
= SSI_DATAAVAILABLE(msg
->channel
);
220 pm_runtime_put_sync(ssi
->device
.parent
);
223 val
= SSI_DATAACCEPT(msg
->channel
);
224 /* Keep clocks reference for write pio event */
226 dma_unmap_sg(&ssi
->device
, msg
->sgt
.sgl
, msg
->sgt
.nents
, dir
);
227 csr
= readw(omap_ssi
->gdd
+ SSI_GDD_CSR_REG(lch
));
228 omap_ssi
->gdd_trn
[lch
].msg
= NULL
; /* release GDD lch */
229 dev_dbg(&port
->device
, "DMA completed ch %d ttype %d\n",
230 msg
->channel
, msg
->ttype
);
231 spin_unlock(&omap_ssi
->lock
);
232 if (csr
& SSI_CSR_TOUR
) { /* Timeout error */
233 msg
->status
= HSI_STATUS_ERROR
;
235 spin_lock(&omap_port
->lock
);
236 list_del(&msg
->link
); /* Dequeue msg */
237 spin_unlock(&omap_port
->lock
);
241 spin_lock(&omap_port
->lock
);
242 val
|= readl(omap_ssi
->sys
+ SSI_MPU_ENABLE_REG(port
->num
, 0));
243 writel_relaxed(val
, omap_ssi
->sys
+ SSI_MPU_ENABLE_REG(port
->num
, 0));
244 spin_unlock(&omap_port
->lock
);
246 msg
->status
= HSI_STATUS_COMPLETED
;
247 msg
->actual_len
= sg_dma_len(msg
->sgt
.sgl
);
250 static void ssi_gdd_tasklet(unsigned long dev
)
252 struct hsi_controller
*ssi
= (struct hsi_controller
*)dev
;
253 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
254 void __iomem
*sys
= omap_ssi
->sys
;
258 pm_runtime_get_sync(ssi
->device
.parent
);
260 status_reg
= readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
261 for (lch
= 0; lch
< SSI_MAX_GDD_LCH
; lch
++) {
262 if (status_reg
& SSI_GDD_LCH(lch
))
263 ssi_gdd_complete(ssi
, lch
);
265 writel_relaxed(status_reg
, sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
266 status_reg
= readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
268 pm_runtime_put_sync(ssi
->device
.parent
);
271 tasklet_hi_schedule(&omap_ssi
->gdd_tasklet
);
273 enable_irq(omap_ssi
->gdd_irq
);
277 static irqreturn_t
ssi_gdd_isr(int irq
, void *ssi
)
279 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
281 tasklet_hi_schedule(&omap_ssi
->gdd_tasklet
);
282 disable_irq_nosync(irq
);
287 static unsigned long ssi_get_clk_rate(struct hsi_controller
*ssi
)
289 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
290 unsigned long rate
= clk_get_rate(omap_ssi
->fck
);
294 static int __init
ssi_get_iomem(struct platform_device
*pd
,
295 const char *name
, void __iomem
**pbase
, dma_addr_t
*phy
)
297 struct resource
*mem
;
298 struct resource
*ioarea
;
300 struct hsi_controller
*ssi
= platform_get_drvdata(pd
);
302 mem
= platform_get_resource_byname(pd
, IORESOURCE_MEM
, name
);
304 dev_err(&pd
->dev
, "IO memory region missing (%s)\n", name
);
307 ioarea
= devm_request_mem_region(&ssi
->device
, mem
->start
,
308 resource_size(mem
), dev_name(&pd
->dev
));
310 dev_err(&pd
->dev
, "%s IO memory region request failed\n",
314 base
= devm_ioremap(&ssi
->device
, mem
->start
, resource_size(mem
));
316 dev_err(&pd
->dev
, "%s IO remap failed\n", mem
->name
);
327 static int __init
ssi_add_controller(struct hsi_controller
*ssi
,
328 struct platform_device
*pd
)
330 struct omap_ssi_controller
*omap_ssi
;
333 omap_ssi
= devm_kzalloc(&ssi
->device
, sizeof(*omap_ssi
), GFP_KERNEL
);
335 dev_err(&pd
->dev
, "not enough memory for omap ssi\n");
339 ssi
->id
= ida_simple_get(&platform_omap_ssi_ida
, 0, 0, GFP_KERNEL
);
345 ssi
->owner
= THIS_MODULE
;
346 ssi
->device
.parent
= &pd
->dev
;
347 dev_set_name(&ssi
->device
, "ssi%d", ssi
->id
);
348 hsi_controller_set_drvdata(ssi
, omap_ssi
);
349 omap_ssi
->dev
= &ssi
->device
;
350 err
= ssi_get_iomem(pd
, "sys", &omap_ssi
->sys
, NULL
);
353 err
= ssi_get_iomem(pd
, "gdd", &omap_ssi
->gdd
, NULL
);
356 err
= platform_get_irq_byname(pd
, "gdd_mpu");
358 dev_err(&pd
->dev
, "GDD IRQ resource missing\n");
361 omap_ssi
->gdd_irq
= err
;
362 tasklet_init(&omap_ssi
->gdd_tasklet
, ssi_gdd_tasklet
,
364 err
= devm_request_irq(&ssi
->device
, omap_ssi
->gdd_irq
, ssi_gdd_isr
,
367 dev_err(&ssi
->device
, "Request GDD IRQ %d failed (%d)",
368 omap_ssi
->gdd_irq
, err
);
372 omap_ssi
->port
= devm_kzalloc(&ssi
->device
,
373 sizeof(struct omap_ssi_port
*) * ssi
->num_ports
, GFP_KERNEL
);
374 if (!omap_ssi
->port
) {
379 omap_ssi
->fck
= devm_clk_get(&ssi
->device
, "ssi_ssr_fck");
380 if (IS_ERR(omap_ssi
->fck
)) {
381 dev_err(&pd
->dev
, "Could not acquire clock \"ssi_ssr_fck\": %li\n",
382 PTR_ERR(omap_ssi
->fck
));
387 /* TODO: find register, which can be used to detect context loss */
388 omap_ssi
->get_loss
= NULL
;
390 omap_ssi
->max_speed
= UINT_MAX
;
391 spin_lock_init(&omap_ssi
->lock
);
392 err
= hsi_register_controller(ssi
);
400 ida_simple_remove(&platform_omap_ssi_ida
, ssi
->id
);
404 static int __init
ssi_hw_init(struct hsi_controller
*ssi
)
406 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
411 err
= pm_runtime_get_sync(ssi
->device
.parent
);
413 dev_err(&ssi
->device
, "runtime PM failed %d\n", err
);
416 /* Reseting SSI controller */
417 writel_relaxed(SSI_SOFTRESET
, omap_ssi
->sys
+ SSI_SYSCONFIG_REG
);
418 val
= readl(omap_ssi
->sys
+ SSI_SYSSTATUS_REG
);
419 for (i
= 0; ((i
< 20) && !(val
& SSI_RESETDONE
)); i
++) {
421 val
= readl(omap_ssi
->sys
+ SSI_SYSSTATUS_REG
);
423 if (!(val
& SSI_RESETDONE
)) {
424 dev_err(&ssi
->device
, "SSI HW reset failed\n");
425 pm_runtime_put_sync(ssi
->device
.parent
);
429 writel_relaxed(SSI_SWRESET
, omap_ssi
->gdd
+ SSI_GDD_GRST_REG
);
430 /* Get FCK rate in KHz */
431 omap_ssi
->fck_rate
= DIV_ROUND_CLOSEST(ssi_get_clk_rate(ssi
), 1000);
432 dev_dbg(&ssi
->device
, "SSI fck rate %lu KHz\n", omap_ssi
->fck_rate
);
433 /* Set default PM settings */
434 val
= SSI_AUTOIDLE
| SSI_SIDLEMODE_SMART
| SSI_MIDLEMODE_SMART
;
435 writel_relaxed(val
, omap_ssi
->sys
+ SSI_SYSCONFIG_REG
);
436 omap_ssi
->sysconfig
= val
;
437 writel_relaxed(SSI_CLK_AUTOGATING_ON
, omap_ssi
->sys
+ SSI_GDD_GCR_REG
);
438 omap_ssi
->gdd_gcr
= SSI_CLK_AUTOGATING_ON
;
439 pm_runtime_put_sync(ssi
->device
.parent
);
444 static void ssi_remove_controller(struct hsi_controller
*ssi
)
446 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
448 tasklet_kill(&omap_ssi
->gdd_tasklet
);
449 hsi_unregister_controller(ssi
);
450 ida_simple_remove(&platform_omap_ssi_ida
, id
);
453 static inline int ssi_of_get_available_ports_count(const struct device_node
*np
)
455 struct device_node
*child
;
458 for_each_available_child_of_node(np
, child
)
459 if (of_device_is_compatible(child
, "ti,omap3-ssi-port"))
465 static int ssi_remove_ports(struct device
*dev
, void *c
)
467 struct platform_device
*pdev
= to_platform_device(dev
);
469 of_device_unregister(pdev
);
474 static int __init
ssi_probe(struct platform_device
*pd
)
476 struct platform_device
*childpdev
;
477 struct device_node
*np
= pd
->dev
.of_node
;
478 struct device_node
*child
;
479 struct hsi_controller
*ssi
;
484 dev_err(&pd
->dev
, "missing device tree data\n");
488 num_ports
= ssi_of_get_available_ports_count(np
);
490 ssi
= hsi_alloc_controller(num_ports
, GFP_KERNEL
);
492 dev_err(&pd
->dev
, "No memory for controller\n");
496 platform_set_drvdata(pd
, ssi
);
498 err
= ssi_add_controller(ssi
, pd
);
502 pm_runtime_irq_safe(&pd
->dev
);
503 pm_runtime_enable(&pd
->dev
);
505 err
= ssi_hw_init(ssi
);
508 #ifdef CONFIG_DEBUG_FS
509 err
= ssi_debug_add_ctrl(ssi
);
514 for_each_available_child_of_node(np
, child
) {
515 if (!of_device_is_compatible(child
, "ti,omap3-ssi-port"))
518 childpdev
= of_platform_device_create(child
, NULL
, &pd
->dev
);
521 dev_err(&pd
->dev
, "failed to create ssi controller port\n");
526 dev_info(&pd
->dev
, "ssi controller %d initialized (%d ports)!\n",
530 device_for_each_child(&pd
->dev
, NULL
, ssi_remove_ports
);
532 ssi_remove_controller(ssi
);
534 platform_set_drvdata(pd
, NULL
);
535 pm_runtime_disable(&pd
->dev
);
540 static int __exit
ssi_remove(struct platform_device
*pd
)
542 struct hsi_controller
*ssi
= platform_get_drvdata(pd
);
544 #ifdef CONFIG_DEBUG_FS
545 ssi_debug_remove_ctrl(ssi
);
547 ssi_remove_controller(ssi
);
548 platform_set_drvdata(pd
, NULL
);
550 pm_runtime_disable(&pd
->dev
);
552 /* cleanup of of_platform_populate() call */
553 device_for_each_child(&pd
->dev
, NULL
, ssi_remove_ports
);
559 static int omap_ssi_runtime_suspend(struct device
*dev
)
561 struct hsi_controller
*ssi
= dev_get_drvdata(dev
);
562 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
564 dev_dbg(dev
, "runtime suspend!\n");
566 if (omap_ssi
->get_loss
)
567 omap_ssi
->loss_count
=
568 omap_ssi
->get_loss(ssi
->device
.parent
);
573 static int omap_ssi_runtime_resume(struct device
*dev
)
575 struct hsi_controller
*ssi
= dev_get_drvdata(dev
);
576 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
578 dev_dbg(dev
, "runtime resume!\n");
580 if ((omap_ssi
->get_loss
) && (omap_ssi
->loss_count
==
581 omap_ssi
->get_loss(ssi
->device
.parent
)))
584 writel_relaxed(omap_ssi
->gdd_gcr
, omap_ssi
->gdd
+ SSI_GDD_GCR_REG
);
589 static const struct dev_pm_ops omap_ssi_pm_ops
= {
590 SET_RUNTIME_PM_OPS(omap_ssi_runtime_suspend
, omap_ssi_runtime_resume
,
594 #define DEV_PM_OPS (&omap_ssi_pm_ops)
596 #define DEV_PM_OPS NULL
600 static const struct of_device_id omap_ssi_of_match
[] = {
601 { .compatible
= "ti,omap3-ssi", },
604 MODULE_DEVICE_TABLE(of
, omap_ssi_of_match
);
606 #define omap_ssi_of_match NULL
609 static struct platform_driver ssi_pdriver
= {
610 .remove
= __exit_p(ssi_remove
),
614 .of_match_table
= omap_ssi_of_match
,
618 module_platform_driver_probe(ssi_pdriver
, ssi_probe
);
620 MODULE_ALIAS("platform:omap_ssi");
621 MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>");
622 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
623 MODULE_DESCRIPTION("Synchronous Serial Interface Driver");
624 MODULE_LICENSE("GPL v2");