1  /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
2  /* Copyright(c) 2015-17 Intel Corporation. */
3  
4  #ifndef __SDW_INTEL_LOCAL_H
5  #define __SDW_INTEL_LOCAL_H
6  
7  struct hdac_bus;
8  
9  /**
10   * struct sdw_intel_link_res - Soundwire Intel link resource structure,
11   * typically populated by the controller driver.
12   * @hw_ops: platform-specific ops
13   * @mmio_base: mmio base of SoundWire registers
14   * @registers: Link IO registers base
15   * @ip_offset: offset for MCP_IP registers
16   * @shim: Audio shim pointer
17   * @shim_vs: Audio vendor-specific shim pointer
18   * @alh: ALH (Audio Link Hub) pointer
19   * @irq: Interrupt line
20   * @ops: Shim callback ops
21   * @dev: device implementing hw_params and free callbacks
22   * @shim_lock: mutex to handle access to shared SHIM registers
23   * @shim_mask: global pointer to check SHIM register initialization
24   * @clock_stop_quirks: mask defining requested behavior on pm_suspend
25   * @link_mask: global mask needed for power-up/down sequences
26   * @cdns: Cadence master descriptor
27   * @list: used to walk-through all masters exposed by the same controller
28   * @hbus: hdac_bus pointer, needed for power management
29   */
30  struct sdw_intel_link_res {
31  	const struct sdw_intel_hw_ops *hw_ops;
32  
33  	void __iomem *mmio_base; /* not strictly needed, useful for debug */
34  	void __iomem *registers;
35  	u32 ip_offset;
36  	void __iomem *shim;
37  	void __iomem *shim_vs;
38  	void __iomem *alh;
39  	int irq;
40  	const struct sdw_intel_ops *ops;
41  	struct device *dev;
42  	struct mutex *shim_lock; /* protect shared registers */
43  	u32 *shim_mask;
44  	u32 clock_stop_quirks;
45  	u32 link_mask;
46  	struct sdw_cdns *cdns;
47  	struct list_head list;
48  	struct hdac_bus *hbus;
49  };
50  
51  struct sdw_intel {
52  	struct sdw_cdns cdns;
53  	int instance;
54  	struct sdw_intel_link_res *link_res;
55  	bool startup_done;
56  #ifdef CONFIG_DEBUG_FS
57  	struct dentry *debugfs;
58  #endif
59  };
60  
61  struct sdw_intel_prop {
62  	u16 clde;
63  	u16 doaise2;
64  	u16 dodse2;
65  	u16 clds;
66  	u16 clss;
67  	u16 doaise;
68  	u16 doais;
69  	u16 dodse;
70  	u16 dods;
71  };
72  
73  enum intel_pdi_type {
74  	INTEL_PDI_IN = 0,
75  	INTEL_PDI_OUT = 1,
76  	INTEL_PDI_BD = 2,
77  };
78  
79  /*
80   * Read, write helpers for HW registers
81   */
intel_readl(void __iomem * base,int offset)82  static inline int intel_readl(void __iomem *base, int offset)
83  {
84  	return readl(base + offset);
85  }
86  
intel_writel(void __iomem * base,int offset,int value)87  static inline void intel_writel(void __iomem *base, int offset, int value)
88  {
89  	writel(value, base + offset);
90  }
91  
intel_readw(void __iomem * base,int offset)92  static inline u16 intel_readw(void __iomem *base, int offset)
93  {
94  	return readw(base + offset);
95  }
96  
intel_writew(void __iomem * base,int offset,u16 value)97  static inline void intel_writew(void __iomem *base, int offset, u16 value)
98  {
99  	writew(value, base + offset);
100  }
101  
102  #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
103  
104  #define INTEL_MASTER_RESET_ITERATIONS	10
105  
106  #define SDW_INTEL_DELAYED_ENUMERATION_MS	100
107  
108  #define SDW_INTEL_CHECK_OPS(sdw, cb)	((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
109  					 (sdw)->link_res->hw_ops->cb)
110  #define SDW_INTEL_OPS(sdw, cb)		((sdw)->link_res->hw_ops->cb)
111  
112  #ifdef CONFIG_DEBUG_FS
113  void intel_ace2x_debugfs_init(struct sdw_intel *sdw);
114  void intel_ace2x_debugfs_exit(struct sdw_intel *sdw);
115  #else
intel_ace2x_debugfs_init(struct sdw_intel * sdw)116  static inline void intel_ace2x_debugfs_init(struct sdw_intel *sdw) {}
intel_ace2x_debugfs_exit(struct sdw_intel * sdw)117  static inline void intel_ace2x_debugfs_exit(struct sdw_intel *sdw) {}
118  #endif
119  
sdw_intel_debugfs_init(struct sdw_intel * sdw)120  static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw)
121  {
122  	if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init))
123  		SDW_INTEL_OPS(sdw, debugfs_init)(sdw);
124  }
125  
sdw_intel_debugfs_exit(struct sdw_intel * sdw)126  static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw)
127  {
128  	if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit))
129  		SDW_INTEL_OPS(sdw, debugfs_exit)(sdw);
130  }
131  
sdw_intel_register_dai(struct sdw_intel * sdw)132  static inline int sdw_intel_register_dai(struct sdw_intel *sdw)
133  {
134  	if (SDW_INTEL_CHECK_OPS(sdw, register_dai))
135  		return SDW_INTEL_OPS(sdw, register_dai)(sdw);
136  	return -ENOTSUPP;
137  }
138  
sdw_intel_check_clock_stop(struct sdw_intel * sdw)139  static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw)
140  {
141  	if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop))
142  		SDW_INTEL_OPS(sdw, check_clock_stop)(sdw);
143  }
144  
sdw_intel_start_bus(struct sdw_intel * sdw)145  static inline int sdw_intel_start_bus(struct sdw_intel *sdw)
146  {
147  	if (SDW_INTEL_CHECK_OPS(sdw, start_bus))
148  		return SDW_INTEL_OPS(sdw, start_bus)(sdw);
149  	return -ENOTSUPP;
150  }
151  
sdw_intel_start_bus_after_reset(struct sdw_intel * sdw)152  static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw)
153  {
154  	if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset))
155  		return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw);
156  	return -ENOTSUPP;
157  }
158  
sdw_intel_start_bus_after_clock_stop(struct sdw_intel * sdw)159  static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
160  {
161  	if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop))
162  		return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw);
163  	return -ENOTSUPP;
164  }
165  
sdw_intel_stop_bus(struct sdw_intel * sdw,bool clock_stop)166  static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
167  {
168  	if (SDW_INTEL_CHECK_OPS(sdw, stop_bus))
169  		return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop);
170  	return -ENOTSUPP;
171  }
172  
sdw_intel_link_power_up(struct sdw_intel * sdw)173  static inline int sdw_intel_link_power_up(struct sdw_intel *sdw)
174  {
175  	if (SDW_INTEL_CHECK_OPS(sdw, link_power_up))
176  		return SDW_INTEL_OPS(sdw, link_power_up)(sdw);
177  	return -ENOTSUPP;
178  }
179  
sdw_intel_link_power_down(struct sdw_intel * sdw)180  static inline int sdw_intel_link_power_down(struct sdw_intel *sdw)
181  {
182  	if (SDW_INTEL_CHECK_OPS(sdw, link_power_down))
183  		return SDW_INTEL_OPS(sdw, link_power_down)(sdw);
184  	return -ENOTSUPP;
185  }
186  
sdw_intel_shim_check_wake(struct sdw_intel * sdw)187  static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw)
188  {
189  	if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake))
190  		return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw);
191  	return -ENOTSUPP;
192  }
193  
sdw_intel_shim_wake(struct sdw_intel * sdw,bool wake_enable)194  static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
195  {
196  	if (SDW_INTEL_CHECK_OPS(sdw, shim_wake))
197  		SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable);
198  }
199  
sdw_intel_sync_arm(struct sdw_intel * sdw)200  static inline void sdw_intel_sync_arm(struct sdw_intel *sdw)
201  {
202  	if (SDW_INTEL_CHECK_OPS(sdw, sync_arm))
203  		SDW_INTEL_OPS(sdw, sync_arm)(sdw);
204  }
205  
sdw_intel_sync_go_unlocked(struct sdw_intel * sdw)206  static inline int sdw_intel_sync_go_unlocked(struct sdw_intel *sdw)
207  {
208  	if (SDW_INTEL_CHECK_OPS(sdw, sync_go_unlocked))
209  		return SDW_INTEL_OPS(sdw, sync_go_unlocked)(sdw);
210  	return -ENOTSUPP;
211  }
212  
sdw_intel_sync_go(struct sdw_intel * sdw)213  static inline int sdw_intel_sync_go(struct sdw_intel *sdw)
214  {
215  	if (SDW_INTEL_CHECK_OPS(sdw, sync_go))
216  		return SDW_INTEL_OPS(sdw, sync_go)(sdw);
217  	return -ENOTSUPP;
218  }
219  
sdw_intel_sync_check_cmdsync_unlocked(struct sdw_intel * sdw)220  static inline bool sdw_intel_sync_check_cmdsync_unlocked(struct sdw_intel *sdw)
221  {
222  	if (SDW_INTEL_CHECK_OPS(sdw, sync_check_cmdsync_unlocked))
223  		return SDW_INTEL_OPS(sdw, sync_check_cmdsync_unlocked)(sdw);
224  	return false;
225  }
226  
sdw_intel_get_link_count(struct sdw_intel * sdw)227  static inline int sdw_intel_get_link_count(struct sdw_intel *sdw)
228  {
229  	if (SDW_INTEL_CHECK_OPS(sdw, get_link_count))
230  		return SDW_INTEL_OPS(sdw, get_link_count)(sdw);
231  	return 4; /* default on older generations */
232  }
233  
234  /* common bus management */
235  int intel_start_bus(struct sdw_intel *sdw);
236  int intel_start_bus_after_reset(struct sdw_intel *sdw);
237  void intel_check_clock_stop(struct sdw_intel *sdw);
238  int intel_start_bus_after_clock_stop(struct sdw_intel *sdw);
239  int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop);
240  
241  /* common bank switch routines */
242  int intel_pre_bank_switch(struct sdw_intel *sdw);
243  int intel_post_bank_switch(struct sdw_intel *sdw);
244  
245  #endif /* __SDW_INTEL_LOCAL_H */
246