162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* OMAP SSI internal interface. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2010 Nokia Corporation. All rights reserved. 562306a36Sopenharmony_ci * Copyright (C) 2013 Sebastian Reichel 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Contact: Carlos Chinea <carlos.chinea@nokia.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef __LINUX_HSI_OMAP_SSI_H__ 1162306a36Sopenharmony_ci#define __LINUX_HSI_OMAP_SSI_H__ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/device.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/platform_device.h> 1662306a36Sopenharmony_ci#include <linux/hsi/hsi.h> 1762306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 1862306a36Sopenharmony_ci#include <linux/interrupt.h> 1962306a36Sopenharmony_ci#include <linux/io.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define SSI_MAX_CHANNELS 8 2262306a36Sopenharmony_ci#define SSI_MAX_GDD_LCH 8 2362306a36Sopenharmony_ci#define SSI_BYTES_TO_FRAMES(x) ((((x) - 1) >> 2) + 1) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define SSI_WAKE_EN 0 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/** 2862306a36Sopenharmony_ci * struct omap_ssm_ctx - OMAP synchronous serial module (TX/RX) context 2962306a36Sopenharmony_ci * @mode: Bit transmission mode 3062306a36Sopenharmony_ci * @channels: Number of channels 3162306a36Sopenharmony_ci * @framesize: Frame size in bits 3262306a36Sopenharmony_ci * @timeout: RX frame timeout 3362306a36Sopenharmony_ci * @divisor: TX divider 3462306a36Sopenharmony_ci * @arb_mode: Arbitration mode for TX frame (Round robin, priority) 3562306a36Sopenharmony_ci */ 3662306a36Sopenharmony_cistruct omap_ssm_ctx { 3762306a36Sopenharmony_ci u32 mode; 3862306a36Sopenharmony_ci u32 channels; 3962306a36Sopenharmony_ci u32 frame_size; 4062306a36Sopenharmony_ci union { 4162306a36Sopenharmony_ci u32 timeout; /* Rx Only */ 4262306a36Sopenharmony_ci struct { 4362306a36Sopenharmony_ci u32 arb_mode; 4462306a36Sopenharmony_ci u32 divisor; 4562306a36Sopenharmony_ci }; /* Tx only */ 4662306a36Sopenharmony_ci }; 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/** 5062306a36Sopenharmony_ci * struct omap_ssi_port - OMAP SSI port data 5162306a36Sopenharmony_ci * @dev: device associated to the port (HSI port) 5262306a36Sopenharmony_ci * @pdev: platform device associated to the port 5362306a36Sopenharmony_ci * @sst_dma: SSI transmitter physical base address 5462306a36Sopenharmony_ci * @ssr_dma: SSI receiver physical base address 5562306a36Sopenharmony_ci * @sst_base: SSI transmitter base address 5662306a36Sopenharmony_ci * @ssr_base: SSI receiver base address 5762306a36Sopenharmony_ci * @wk_lock: spin lock to serialize access to the wake lines 5862306a36Sopenharmony_ci * @lock: Spin lock to serialize access to the SSI port 5962306a36Sopenharmony_ci * @channels: Current number of channels configured (1,2,4 or 8) 6062306a36Sopenharmony_ci * @txqueue: TX message queues 6162306a36Sopenharmony_ci * @rxqueue: RX message queues 6262306a36Sopenharmony_ci * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode) 6362306a36Sopenharmony_ci * @errqueue: Queue for failed messages 6462306a36Sopenharmony_ci * @errqueue_work: Delayed Work for failed messages 6562306a36Sopenharmony_ci * @irq: IRQ number 6662306a36Sopenharmony_ci * @wake_irq: IRQ number for incoming wake line (-1 if none) 6762306a36Sopenharmony_ci * @wake_gpio: GPIO number for incoming wake line (-1 if none) 6862306a36Sopenharmony_ci * @flags: flags to keep track of states 6962306a36Sopenharmony_ci * @wk_refcount: Reference count for output wake line 7062306a36Sopenharmony_ci * @work: worker for starting TX 7162306a36Sopenharmony_ci * @sys_mpu_enable: Context for the interrupt enable register for irq 0 7262306a36Sopenharmony_ci * @sst: Context for the synchronous serial transmitter 7362306a36Sopenharmony_ci * @ssr: Context for the synchronous serial receiver 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_cistruct omap_ssi_port { 7662306a36Sopenharmony_ci struct device *dev; 7762306a36Sopenharmony_ci struct device *pdev; 7862306a36Sopenharmony_ci dma_addr_t sst_dma; 7962306a36Sopenharmony_ci dma_addr_t ssr_dma; 8062306a36Sopenharmony_ci void __iomem *sst_base; 8162306a36Sopenharmony_ci void __iomem *ssr_base; 8262306a36Sopenharmony_ci spinlock_t wk_lock; 8362306a36Sopenharmony_ci spinlock_t lock; 8462306a36Sopenharmony_ci unsigned int channels; 8562306a36Sopenharmony_ci struct list_head txqueue[SSI_MAX_CHANNELS]; 8662306a36Sopenharmony_ci struct list_head rxqueue[SSI_MAX_CHANNELS]; 8762306a36Sopenharmony_ci struct list_head brkqueue; 8862306a36Sopenharmony_ci struct list_head errqueue; 8962306a36Sopenharmony_ci struct delayed_work errqueue_work; 9062306a36Sopenharmony_ci unsigned int irq; 9162306a36Sopenharmony_ci int wake_irq; 9262306a36Sopenharmony_ci struct gpio_desc *wake_gpio; 9362306a36Sopenharmony_ci bool wktest:1; /* FIXME: HACK to be removed */ 9462306a36Sopenharmony_ci unsigned long flags; 9562306a36Sopenharmony_ci unsigned int wk_refcount; 9662306a36Sopenharmony_ci struct work_struct work; 9762306a36Sopenharmony_ci /* OMAP SSI port context */ 9862306a36Sopenharmony_ci u32 sys_mpu_enable; /* We use only one irq */ 9962306a36Sopenharmony_ci struct omap_ssm_ctx sst; 10062306a36Sopenharmony_ci struct omap_ssm_ctx ssr; 10162306a36Sopenharmony_ci u32 loss_count; 10262306a36Sopenharmony_ci u32 port_id; 10362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 10462306a36Sopenharmony_ci struct dentry *dir; 10562306a36Sopenharmony_ci#endif 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/** 10962306a36Sopenharmony_ci * struct gdd_trn - GDD transaction data 11062306a36Sopenharmony_ci * @msg: Pointer to the HSI message being served 11162306a36Sopenharmony_ci * @sg: Pointer to the current sg entry being served 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_cistruct gdd_trn { 11462306a36Sopenharmony_ci struct hsi_msg *msg; 11562306a36Sopenharmony_ci struct scatterlist *sg; 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/** 11962306a36Sopenharmony_ci * struct omap_ssi_controller - OMAP SSI controller data 12062306a36Sopenharmony_ci * @dev: device associated to the controller (HSI controller) 12162306a36Sopenharmony_ci * @sys: SSI I/O base address 12262306a36Sopenharmony_ci * @gdd: GDD I/O base address 12362306a36Sopenharmony_ci * @fck: SSI functional clock 12462306a36Sopenharmony_ci * @gdd_irq: IRQ line for GDD 12562306a36Sopenharmony_ci * @gdd_tasklet: bottom half for DMA transfers 12662306a36Sopenharmony_ci * @gdd_trn: Array of GDD transaction data for ongoing GDD transfers 12762306a36Sopenharmony_ci * @lock: lock to serialize access to GDD 12862306a36Sopenharmony_ci * @fck_nb: DVFS notfifier block 12962306a36Sopenharmony_ci * @fck_rate: clock rate 13062306a36Sopenharmony_ci * @loss_count: To follow if we need to restore context or not 13162306a36Sopenharmony_ci * @max_speed: Maximum TX speed (Kb/s) set by the clients. 13262306a36Sopenharmony_ci * @gdd_gcr: SSI GDD saved context 13362306a36Sopenharmony_ci * @get_loss: Pointer to omap_pm_get_dev_context_loss_count, if any 13462306a36Sopenharmony_ci * @port: Array of pointers of the ports of the controller 13562306a36Sopenharmony_ci * @dir: Debugfs SSI root directory 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_cistruct omap_ssi_controller { 13862306a36Sopenharmony_ci struct device *dev; 13962306a36Sopenharmony_ci void __iomem *sys; 14062306a36Sopenharmony_ci void __iomem *gdd; 14162306a36Sopenharmony_ci struct clk *fck; 14262306a36Sopenharmony_ci unsigned int gdd_irq; 14362306a36Sopenharmony_ci struct tasklet_struct gdd_tasklet; 14462306a36Sopenharmony_ci struct gdd_trn gdd_trn[SSI_MAX_GDD_LCH]; 14562306a36Sopenharmony_ci spinlock_t lock; 14662306a36Sopenharmony_ci struct notifier_block fck_nb; 14762306a36Sopenharmony_ci unsigned long fck_rate; 14862306a36Sopenharmony_ci u32 loss_count; 14962306a36Sopenharmony_ci u32 max_speed; 15062306a36Sopenharmony_ci /* OMAP SSI Controller context */ 15162306a36Sopenharmony_ci u32 gdd_gcr; 15262306a36Sopenharmony_ci int (*get_loss)(struct device *dev); 15362306a36Sopenharmony_ci struct omap_ssi_port **port; 15462306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 15562306a36Sopenharmony_ci struct dentry *dir; 15662306a36Sopenharmony_ci#endif 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_civoid omap_ssi_port_update_fclk(struct hsi_controller *ssi, 16062306a36Sopenharmony_ci struct omap_ssi_port *omap_port); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ciextern struct platform_driver ssi_port_pdriver; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci#endif /* __LINUX_HSI_OMAP_SSI_H__ */ 165