1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
5 * Copyright (C) 2014 Sebastian Reichel <sre@kernel.org>
7 * Contact: Carlos Chinea <carlos.chinea@nokia.com>
10 #include <linux/compiler.h>
11 #include <linux/err.h>
12 #include <linux/ioport.h>
14 #include <linux/clk.h>
15 #include <linux/device.h>
16 #include <linux/platform_device.h>
17 #include <linux/dma-mapping.h>
18 #include <linux/dmaengine.h>
19 #include <linux/delay.h>
20 #include <linux/hsi/ssi_protocol.h>
21 #include <linux/seq_file.h>
22 #include <linux/scatterlist.h>
23 #include <linux/interrupt.h>
24 #include <linux/spinlock.h>
25 #include <linux/debugfs.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/pm_runtime.h>
29 #include <linux/of_platform.h>
30 #include <linux/hsi/hsi.h>
31 #include <linux/idr.h>
33 #include "omap_ssi_regs.h"
36 /* For automatically allocated device IDs */
37 static DEFINE_IDA(platform_omap_ssi_ida
);
39 #ifdef CONFIG_DEBUG_FS
40 static int ssi_regs_show(struct seq_file
*m
, void *p __maybe_unused
)
42 struct hsi_controller
*ssi
= m
->private;
43 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
44 void __iomem
*sys
= omap_ssi
->sys
;
46 pm_runtime_get_sync(ssi
->device
.parent
);
47 seq_printf(m
, "REVISION\t: 0x%08x\n", readl(sys
+ SSI_REVISION_REG
));
48 seq_printf(m
, "SYSCONFIG\t: 0x%08x\n", readl(sys
+ SSI_SYSCONFIG_REG
));
49 seq_printf(m
, "SYSSTATUS\t: 0x%08x\n", readl(sys
+ SSI_SYSSTATUS_REG
));
50 pm_runtime_put(ssi
->device
.parent
);
55 static int ssi_gdd_regs_show(struct seq_file
*m
, void *p __maybe_unused
)
57 struct hsi_controller
*ssi
= m
->private;
58 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
59 void __iomem
*gdd
= omap_ssi
->gdd
;
60 void __iomem
*sys
= omap_ssi
->sys
;
63 pm_runtime_get_sync(ssi
->device
.parent
);
65 seq_printf(m
, "GDD_MPU_STATUS\t: 0x%08x\n",
66 readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
));
67 seq_printf(m
, "GDD_MPU_ENABLE\t: 0x%08x\n\n",
68 readl(sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
));
69 seq_printf(m
, "HW_ID\t\t: 0x%08x\n",
70 readl(gdd
+ SSI_GDD_HW_ID_REG
));
71 seq_printf(m
, "PPORT_ID\t: 0x%08x\n",
72 readl(gdd
+ SSI_GDD_PPORT_ID_REG
));
73 seq_printf(m
, "MPORT_ID\t: 0x%08x\n",
74 readl(gdd
+ SSI_GDD_MPORT_ID_REG
));
75 seq_printf(m
, "TEST\t\t: 0x%08x\n",
76 readl(gdd
+ SSI_GDD_TEST_REG
));
77 seq_printf(m
, "GCR\t\t: 0x%08x\n",
78 readl(gdd
+ SSI_GDD_GCR_REG
));
80 for (lch
= 0; lch
< SSI_MAX_GDD_LCH
; lch
++) {
81 seq_printf(m
, "\nGDD LCH %d\n=========\n", lch
);
82 seq_printf(m
, "CSDP\t\t: 0x%04x\n",
83 readw(gdd
+ SSI_GDD_CSDP_REG(lch
)));
84 seq_printf(m
, "CCR\t\t: 0x%04x\n",
85 readw(gdd
+ SSI_GDD_CCR_REG(lch
)));
86 seq_printf(m
, "CICR\t\t: 0x%04x\n",
87 readw(gdd
+ SSI_GDD_CICR_REG(lch
)));
88 seq_printf(m
, "CSR\t\t: 0x%04x\n",
89 readw(gdd
+ SSI_GDD_CSR_REG(lch
)));
90 seq_printf(m
, "CSSA\t\t: 0x%08x\n",
91 readl(gdd
+ SSI_GDD_CSSA_REG(lch
)));
92 seq_printf(m
, "CDSA\t\t: 0x%08x\n",
93 readl(gdd
+ SSI_GDD_CDSA_REG(lch
)));
94 seq_printf(m
, "CEN\t\t: 0x%04x\n",
95 readw(gdd
+ SSI_GDD_CEN_REG(lch
)));
96 seq_printf(m
, "CSAC\t\t: 0x%04x\n",
97 readw(gdd
+ SSI_GDD_CSAC_REG(lch
)));
98 seq_printf(m
, "CDAC\t\t: 0x%04x\n",
99 readw(gdd
+ SSI_GDD_CDAC_REG(lch
)));
100 seq_printf(m
, "CLNK_CTRL\t: 0x%04x\n",
101 readw(gdd
+ SSI_GDD_CLNK_CTRL_REG(lch
)));
104 pm_runtime_put(ssi
->device
.parent
);
109 DEFINE_SHOW_ATTRIBUTE(ssi_regs
);
110 DEFINE_SHOW_ATTRIBUTE(ssi_gdd_regs
);
112 static int ssi_debug_add_ctrl(struct hsi_controller
*ssi
)
114 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
118 omap_ssi
->dir
= debugfs_create_dir(dev_name(&ssi
->device
), NULL
);
119 debugfs_create_file("regs", S_IRUGO
, omap_ssi
->dir
, ssi
, &ssi_regs_fops
);
122 dir
= debugfs_create_dir("gdd", omap_ssi
->dir
);
123 debugfs_create_file("regs", S_IRUGO
, dir
, ssi
, &ssi_gdd_regs_fops
);
128 static void ssi_debug_remove_ctrl(struct hsi_controller
*ssi
)
130 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
132 debugfs_remove_recursive(omap_ssi
->dir
);
134 #endif /* CONFIG_DEBUG_FS */
137 * FIXME: Horrible HACK needed until we remove the useless wakeline test
138 * in the CMT. To be removed !!!!
140 void ssi_waketest(struct hsi_client
*cl
, unsigned int enable
)
142 struct hsi_port
*port
= hsi_get_port(cl
);
143 struct omap_ssi_port
*omap_port
= hsi_port_drvdata(port
);
144 struct hsi_controller
*ssi
= to_hsi_controller(port
->device
.parent
);
145 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
147 omap_port
->wktest
= !!enable
;
148 if (omap_port
->wktest
) {
149 pm_runtime_get_sync(ssi
->device
.parent
);
150 writel_relaxed(SSI_WAKE(0),
151 omap_ssi
->sys
+ SSI_SET_WAKE_REG(port
->num
));
153 writel_relaxed(SSI_WAKE(0),
154 omap_ssi
->sys
+ SSI_CLEAR_WAKE_REG(port
->num
));
155 pm_runtime_put(ssi
->device
.parent
);
158 EXPORT_SYMBOL_GPL(ssi_waketest
);
160 static void ssi_gdd_complete(struct hsi_controller
*ssi
, unsigned int lch
)
162 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
163 struct hsi_msg
*msg
= omap_ssi
->gdd_trn
[lch
].msg
;
164 struct hsi_port
*port
= to_hsi_port(msg
->cl
->device
.parent
);
165 struct omap_ssi_port
*omap_port
= hsi_port_drvdata(port
);
170 spin_lock(&omap_ssi
->lock
);
172 val
= readl(omap_ssi
->sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
);
173 val
&= ~SSI_GDD_LCH(lch
);
174 writel_relaxed(val
, omap_ssi
->sys
+ SSI_GDD_MPU_IRQ_ENABLE_REG
);
176 if (msg
->ttype
== HSI_MSG_READ
) {
177 dir
= DMA_FROM_DEVICE
;
178 val
= SSI_DATAAVAILABLE(msg
->channel
);
179 pm_runtime_put(omap_port
->pdev
);
182 val
= SSI_DATAACCEPT(msg
->channel
);
183 /* Keep clocks reference for write pio event */
185 dma_unmap_sg(&ssi
->device
, msg
->sgt
.sgl
, msg
->sgt
.nents
, dir
);
186 csr
= readw(omap_ssi
->gdd
+ SSI_GDD_CSR_REG(lch
));
187 omap_ssi
->gdd_trn
[lch
].msg
= NULL
; /* release GDD lch */
188 dev_dbg(&port
->device
, "DMA completed ch %d ttype %d\n",
189 msg
->channel
, msg
->ttype
);
190 spin_unlock(&omap_ssi
->lock
);
191 if (csr
& SSI_CSR_TOUR
) { /* Timeout error */
192 msg
->status
= HSI_STATUS_ERROR
;
194 spin_lock(&omap_port
->lock
);
195 list_del(&msg
->link
); /* Dequeue msg */
196 spin_unlock(&omap_port
->lock
);
198 list_add_tail(&msg
->link
, &omap_port
->errqueue
);
199 schedule_delayed_work(&omap_port
->errqueue_work
, 0);
202 spin_lock(&omap_port
->lock
);
203 val
|= readl(omap_ssi
->sys
+ SSI_MPU_ENABLE_REG(port
->num
, 0));
204 writel_relaxed(val
, omap_ssi
->sys
+ SSI_MPU_ENABLE_REG(port
->num
, 0));
205 spin_unlock(&omap_port
->lock
);
207 msg
->status
= HSI_STATUS_COMPLETED
;
208 msg
->actual_len
= sg_dma_len(msg
->sgt
.sgl
);
211 static void ssi_gdd_tasklet(unsigned long dev
)
213 struct hsi_controller
*ssi
= (struct hsi_controller
*)dev
;
214 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
215 void __iomem
*sys
= omap_ssi
->sys
;
219 pm_runtime_get(ssi
->device
.parent
);
221 if (!pm_runtime_active(ssi
->device
.parent
)) {
222 dev_warn(ssi
->device
.parent
, "ssi_gdd_tasklet called without runtime PM!\n");
223 pm_runtime_put(ssi
->device
.parent
);
227 status_reg
= readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
228 for (lch
= 0; lch
< SSI_MAX_GDD_LCH
; lch
++) {
229 if (status_reg
& SSI_GDD_LCH(lch
))
230 ssi_gdd_complete(ssi
, lch
);
232 writel_relaxed(status_reg
, sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
233 status_reg
= readl(sys
+ SSI_GDD_MPU_IRQ_STATUS_REG
);
235 pm_runtime_put(ssi
->device
.parent
);
238 tasklet_hi_schedule(&omap_ssi
->gdd_tasklet
);
240 enable_irq(omap_ssi
->gdd_irq
);
244 static irqreturn_t
ssi_gdd_isr(int irq
, void *ssi
)
246 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
248 tasklet_hi_schedule(&omap_ssi
->gdd_tasklet
);
249 disable_irq_nosync(irq
);
254 static unsigned long ssi_get_clk_rate(struct hsi_controller
*ssi
)
256 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
257 unsigned long rate
= clk_get_rate(omap_ssi
->fck
);
261 static int ssi_clk_event(struct notifier_block
*nb
, unsigned long event
,
264 struct omap_ssi_controller
*omap_ssi
= container_of(nb
,
265 struct omap_ssi_controller
, fck_nb
);
266 struct hsi_controller
*ssi
= to_hsi_controller(omap_ssi
->dev
);
267 struct clk_notifier_data
*clk_data
= data
;
268 struct omap_ssi_port
*omap_port
;
272 case PRE_RATE_CHANGE
:
273 dev_dbg(&ssi
->device
, "pre rate change\n");
275 for (i
= 0; i
< ssi
->num_ports
; i
++) {
276 omap_port
= omap_ssi
->port
[i
];
281 /* Workaround for SWBREAK + CAwake down race in CMT */
282 disable_irq(omap_port
->wake_irq
);
284 /* stop all ssi communication */
285 pinctrl_pm_select_idle_state(omap_port
->pdev
);
286 udelay(1); /* wait for racing frames */
290 case ABORT_RATE_CHANGE
:
291 dev_dbg(&ssi
->device
, "abort rate change\n");
293 case POST_RATE_CHANGE
:
294 dev_dbg(&ssi
->device
, "post rate change (%lu -> %lu)\n",
295 clk_data
->old_rate
, clk_data
->new_rate
);
296 omap_ssi
->fck_rate
= DIV_ROUND_CLOSEST(clk_data
->new_rate
, 1000); /* kHz */
298 for (i
= 0; i
< ssi
->num_ports
; i
++) {
299 omap_port
= omap_ssi
->port
[i
];
304 omap_ssi_port_update_fclk(ssi
, omap_port
);
306 /* resume ssi communication */
307 pinctrl_pm_select_default_state(omap_port
->pdev
);
308 enable_irq(omap_port
->wake_irq
);
319 static int ssi_get_iomem(struct platform_device
*pd
,
320 const char *name
, void __iomem
**pbase
, dma_addr_t
*phy
)
322 struct resource
*mem
;
324 struct hsi_controller
*ssi
= platform_get_drvdata(pd
);
326 mem
= platform_get_resource_byname(pd
, IORESOURCE_MEM
, name
);
327 base
= devm_ioremap_resource(&ssi
->device
, mem
);
329 return PTR_ERR(base
);
339 static int ssi_add_controller(struct hsi_controller
*ssi
,
340 struct platform_device
*pd
)
342 struct omap_ssi_controller
*omap_ssi
;
345 omap_ssi
= devm_kzalloc(&ssi
->device
, sizeof(*omap_ssi
), GFP_KERNEL
);
349 err
= ida_alloc(&platform_omap_ssi_ida
, GFP_KERNEL
);
354 ssi
->owner
= THIS_MODULE
;
355 ssi
->device
.parent
= &pd
->dev
;
356 dev_set_name(&ssi
->device
, "ssi%d", ssi
->id
);
357 hsi_controller_set_drvdata(ssi
, omap_ssi
);
358 omap_ssi
->dev
= &ssi
->device
;
359 err
= ssi_get_iomem(pd
, "sys", &omap_ssi
->sys
, NULL
);
362 err
= ssi_get_iomem(pd
, "gdd", &omap_ssi
->gdd
, NULL
);
365 err
= platform_get_irq_byname(pd
, "gdd_mpu");
368 omap_ssi
->gdd_irq
= err
;
369 tasklet_init(&omap_ssi
->gdd_tasklet
, ssi_gdd_tasklet
,
371 err
= devm_request_irq(&ssi
->device
, omap_ssi
->gdd_irq
, ssi_gdd_isr
,
374 dev_err(&ssi
->device
, "Request GDD IRQ %d failed (%d)",
375 omap_ssi
->gdd_irq
, err
);
379 omap_ssi
->port
= devm_kcalloc(&ssi
->device
, ssi
->num_ports
,
380 sizeof(*omap_ssi
->port
), GFP_KERNEL
);
381 if (!omap_ssi
->port
) {
386 omap_ssi
->fck
= devm_clk_get(&ssi
->device
, "ssi_ssr_fck");
387 if (IS_ERR(omap_ssi
->fck
)) {
388 dev_err(&pd
->dev
, "Could not acquire clock \"ssi_ssr_fck\": %li\n",
389 PTR_ERR(omap_ssi
->fck
));
394 omap_ssi
->fck_nb
.notifier_call
= ssi_clk_event
;
395 omap_ssi
->fck_nb
.priority
= INT_MAX
;
396 clk_notifier_register(omap_ssi
->fck
, &omap_ssi
->fck_nb
);
398 /* TODO: find register, which can be used to detect context loss */
399 omap_ssi
->get_loss
= NULL
;
401 omap_ssi
->max_speed
= UINT_MAX
;
402 spin_lock_init(&omap_ssi
->lock
);
403 err
= hsi_register_controller(ssi
);
411 ida_free(&platform_omap_ssi_ida
, ssi
->id
);
415 static int ssi_hw_init(struct hsi_controller
*ssi
)
417 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
420 err
= pm_runtime_resume_and_get(ssi
->device
.parent
);
422 dev_err(&ssi
->device
, "runtime PM failed %d\n", err
);
426 writel_relaxed(SSI_SWRESET
, omap_ssi
->gdd
+ SSI_GDD_GRST_REG
);
427 /* Get FCK rate in kHz */
428 omap_ssi
->fck_rate
= DIV_ROUND_CLOSEST(ssi_get_clk_rate(ssi
), 1000);
429 dev_dbg(&ssi
->device
, "SSI fck rate %lu kHz\n", omap_ssi
->fck_rate
);
431 writel_relaxed(SSI_CLK_AUTOGATING_ON
, omap_ssi
->sys
+ SSI_GDD_GCR_REG
);
432 omap_ssi
->gdd_gcr
= SSI_CLK_AUTOGATING_ON
;
433 pm_runtime_put_sync(ssi
->device
.parent
);
438 static void ssi_remove_controller(struct hsi_controller
*ssi
)
440 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
442 tasklet_kill(&omap_ssi
->gdd_tasklet
);
443 hsi_unregister_controller(ssi
);
444 clk_notifier_unregister(omap_ssi
->fck
, &omap_ssi
->fck_nb
);
445 ida_free(&platform_omap_ssi_ida
, id
);
448 static inline int ssi_of_get_available_ports_count(const struct device_node
*np
)
450 struct device_node
*child
;
453 for_each_available_child_of_node(np
, child
)
454 if (of_device_is_compatible(child
, "ti,omap3-ssi-port"))
460 static int ssi_remove_ports(struct device
*dev
, void *c
)
462 struct platform_device
*pdev
= to_platform_device(dev
);
467 of_node_clear_flag(dev
->of_node
, OF_POPULATED
);
468 of_device_unregister(pdev
);
473 static int ssi_probe(struct platform_device
*pd
)
475 struct platform_device
*childpdev
;
476 struct device_node
*np
= pd
->dev
.of_node
;
477 struct device_node
*child
;
478 struct hsi_controller
*ssi
;
483 dev_err(&pd
->dev
, "missing device tree data\n");
487 num_ports
= ssi_of_get_available_ports_count(np
);
489 ssi
= hsi_alloc_controller(num_ports
, GFP_KERNEL
);
491 dev_err(&pd
->dev
, "No memory for controller\n");
495 platform_set_drvdata(pd
, ssi
);
497 err
= ssi_add_controller(ssi
, pd
);
499 hsi_put_controller(ssi
);
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");
527 dev_info(&pd
->dev
, "ssi controller %d initialized (%d ports)!\n",
531 device_for_each_child(&pd
->dev
, NULL
, ssi_remove_ports
);
533 ssi_remove_controller(ssi
);
534 pm_runtime_disable(&pd
->dev
);
536 platform_set_drvdata(pd
, NULL
);
541 static void ssi_remove(struct platform_device
*pd
)
543 struct hsi_controller
*ssi
= platform_get_drvdata(pd
);
545 /* cleanup of of_platform_populate() call */
546 device_for_each_child(&pd
->dev
, NULL
, ssi_remove_ports
);
548 #ifdef CONFIG_DEBUG_FS
549 ssi_debug_remove_ctrl(ssi
);
551 ssi_remove_controller(ssi
);
552 platform_set_drvdata(pd
, NULL
);
554 pm_runtime_disable(&pd
->dev
);
558 static int omap_ssi_runtime_suspend(struct device
*dev
)
560 struct hsi_controller
*ssi
= dev_get_drvdata(dev
);
561 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
563 dev_dbg(dev
, "runtime suspend!\n");
565 if (omap_ssi
->get_loss
)
566 omap_ssi
->loss_count
=
567 omap_ssi
->get_loss(ssi
->device
.parent
);
572 static int omap_ssi_runtime_resume(struct device
*dev
)
574 struct hsi_controller
*ssi
= dev_get_drvdata(dev
);
575 struct omap_ssi_controller
*omap_ssi
= hsi_controller_drvdata(ssi
);
577 dev_dbg(dev
, "runtime resume!\n");
579 if ((omap_ssi
->get_loss
) && (omap_ssi
->loss_count
==
580 omap_ssi
->get_loss(ssi
->device
.parent
)))
583 writel_relaxed(omap_ssi
->gdd_gcr
, omap_ssi
->gdd
+ SSI_GDD_GCR_REG
);
588 static const struct dev_pm_ops omap_ssi_pm_ops
= {
589 SET_RUNTIME_PM_OPS(omap_ssi_runtime_suspend
, omap_ssi_runtime_resume
,
593 #define DEV_PM_OPS (&omap_ssi_pm_ops)
595 #define DEV_PM_OPS NULL
599 static const struct of_device_id omap_ssi_of_match
[] = {
600 { .compatible
= "ti,omap3-ssi", },
603 MODULE_DEVICE_TABLE(of
, omap_ssi_of_match
);
605 #define omap_ssi_of_match NULL
608 static struct platform_driver ssi_pdriver
= {
610 .remove
= ssi_remove
,
614 .of_match_table
= omap_ssi_of_match
,
618 static int __init
ssi_init(void) {
621 ret
= platform_driver_register(&ssi_pdriver
);
625 ret
= platform_driver_register(&ssi_port_pdriver
);
627 platform_driver_unregister(&ssi_pdriver
);
633 module_init(ssi_init
);
635 static void __exit
ssi_exit(void) {
636 platform_driver_unregister(&ssi_port_pdriver
);
637 platform_driver_unregister(&ssi_pdriver
);
639 module_exit(ssi_exit
);
641 MODULE_ALIAS("platform:omap_ssi");
642 MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>");
643 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
644 MODULE_DESCRIPTION("Synchronous Serial Interface Driver");
645 MODULE_LICENSE("GPL v2");