.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | | - * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 and |
---|
6 | | - * only version 2 as published by the Free Software Foundation. |
---|
7 | | - * |
---|
8 | | - * This program is distributed in the hope that it will be useful, |
---|
9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
10 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
11 | | - * GNU General Public License for more details. |
---|
| 3 | + * Copyright (c) 2010-2011,2013-2015,2020 The Linux Foundation. All rights reserved. |
---|
12 | 4 | * |
---|
13 | 5 | * lpass.h - Definitions for the QTi LPASS |
---|
14 | 6 | */ |
---|
.. | .. |
---|
20 | 12 | #include <linux/compiler.h> |
---|
21 | 13 | #include <linux/platform_device.h> |
---|
22 | 14 | #include <linux/regmap.h> |
---|
| 15 | +#include <dt-bindings/sound/qcom,lpass.h> |
---|
| 16 | +#include "lpass-hdmi.h" |
---|
23 | 17 | |
---|
24 | 18 | #define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 |
---|
25 | 19 | #define LPASS_MAX_MI2S_PORTS (8) |
---|
26 | 20 | #define LPASS_MAX_DMA_CHANNELS (8) |
---|
| 21 | +#define LPASS_MAX_HDMI_DMA_CHANNELS (4) |
---|
| 22 | + |
---|
| 23 | +#define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf) \ |
---|
| 24 | + do { \ |
---|
| 25 | + mf = devm_regmap_field_alloc(d, m, f); \ |
---|
| 26 | + if (IS_ERR(mf)) \ |
---|
| 27 | + return -EINVAL; \ |
---|
| 28 | + } while (0) |
---|
| 29 | + |
---|
| 30 | +struct lpaif_i2sctl { |
---|
| 31 | + struct regmap_field *loopback; |
---|
| 32 | + struct regmap_field *spken; |
---|
| 33 | + struct regmap_field *spkmode; |
---|
| 34 | + struct regmap_field *spkmono; |
---|
| 35 | + struct regmap_field *micen; |
---|
| 36 | + struct regmap_field *micmode; |
---|
| 37 | + struct regmap_field *micmono; |
---|
| 38 | + struct regmap_field *wssrc; |
---|
| 39 | + struct regmap_field *bitwidth; |
---|
| 40 | +}; |
---|
| 41 | + |
---|
| 42 | + |
---|
| 43 | +struct lpaif_dmactl { |
---|
| 44 | + struct regmap_field *intf; |
---|
| 45 | + struct regmap_field *bursten; |
---|
| 46 | + struct regmap_field *wpscnt; |
---|
| 47 | + struct regmap_field *fifowm; |
---|
| 48 | + struct regmap_field *enable; |
---|
| 49 | + struct regmap_field *dyncclk; |
---|
| 50 | + struct regmap_field *burst8; |
---|
| 51 | + struct regmap_field *burst16; |
---|
| 52 | + struct regmap_field *dynburst; |
---|
| 53 | +}; |
---|
27 | 54 | |
---|
28 | 55 | /* Both the CPU DAI and platform drivers will access this data */ |
---|
29 | 56 | struct lpass_data { |
---|
.. | .. |
---|
37 | 64 | /* MI2S bit clock (derived from system clock by a divider */ |
---|
38 | 65 | struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS]; |
---|
39 | 66 | |
---|
| 67 | + /* MI2S SD lines to use for playback/capture */ |
---|
| 68 | + unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; |
---|
| 69 | + unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; |
---|
| 70 | + |
---|
| 71 | + /* The state of MI2S prepare dai_ops was called */ |
---|
| 72 | + bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS]; |
---|
| 73 | + |
---|
| 74 | + int hdmi_port_enable; |
---|
| 75 | + |
---|
40 | 76 | /* low-power audio interface (LPAIF) registers */ |
---|
41 | 77 | void __iomem *lpaif; |
---|
| 78 | + void __iomem *hdmiif; |
---|
42 | 79 | |
---|
43 | 80 | /* regmap backed by the low-power audio interface (LPAIF) registers */ |
---|
44 | 81 | struct regmap *lpaif_map; |
---|
| 82 | + struct regmap *hdmiif_map; |
---|
45 | 83 | |
---|
46 | 84 | /* interrupts from the low-power audio interface (LPAIF) */ |
---|
47 | 85 | int lpaif_irq; |
---|
48 | | - |
---|
| 86 | + int hdmiif_irq; |
---|
49 | 87 | /* SOC specific variations in the LPASS IP integration */ |
---|
50 | 88 | struct lpass_variant *variant; |
---|
51 | 89 | |
---|
52 | 90 | /* bit map to keep track of static channel allocations */ |
---|
53 | 91 | unsigned long dma_ch_bit_map; |
---|
| 92 | + unsigned long hdmi_dma_ch_bit_map; |
---|
54 | 93 | |
---|
55 | 94 | /* used it for handling interrupt per dma channel */ |
---|
56 | 95 | struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS]; |
---|
| 96 | + struct snd_pcm_substream *hdmi_substream[LPASS_MAX_HDMI_DMA_CHANNELS]; |
---|
57 | 97 | |
---|
58 | | - /* 8016 specific */ |
---|
59 | | - struct clk *pcnoc_mport_clk; |
---|
60 | | - struct clk *pcnoc_sway_clk; |
---|
| 98 | + /* SOC specific clock list */ |
---|
| 99 | + struct clk_bulk_data *clks; |
---|
| 100 | + int num_clks; |
---|
61 | 101 | |
---|
| 102 | + /* Regmap fields of I2SCTL & DMACTL registers bitfields */ |
---|
| 103 | + struct lpaif_i2sctl *i2sctl; |
---|
| 104 | + struct lpaif_dmactl *rd_dmactl; |
---|
| 105 | + struct lpaif_dmactl *wr_dmactl; |
---|
| 106 | + struct lpaif_dmactl *hdmi_rd_dmactl; |
---|
| 107 | + /* Regmap fields of HDMI_CTRL registers*/ |
---|
| 108 | + struct regmap_field *hdmitx_legacy_en; |
---|
| 109 | + struct regmap_field *hdmitx_parity_calc_en; |
---|
| 110 | + struct regmap_field *hdmitx_ch_msb[LPASS_MAX_HDMI_DMA_CHANNELS]; |
---|
| 111 | + struct regmap_field *hdmitx_ch_lsb[LPASS_MAX_HDMI_DMA_CHANNELS]; |
---|
| 112 | + struct lpass_hdmi_tx_ctl *tx_ctl; |
---|
| 113 | + struct lpass_vbit_ctrl *vbit_ctl; |
---|
| 114 | + struct lpass_hdmitx_dmactl *hdmi_tx_dmactl[LPASS_MAX_HDMI_DMA_CHANNELS]; |
---|
| 115 | + struct lpass_dp_metadata_ctl *meta_ctl; |
---|
| 116 | + struct lpass_sstream_ctl *sstream_ctl; |
---|
62 | 117 | }; |
---|
63 | 118 | |
---|
64 | 119 | /* Vairant data per each SOC */ |
---|
65 | 120 | struct lpass_variant { |
---|
66 | | - u32 i2sctrl_reg_base; |
---|
67 | | - u32 i2sctrl_reg_stride; |
---|
68 | | - u32 i2s_ports; |
---|
69 | 121 | u32 irq_reg_base; |
---|
70 | 122 | u32 irq_reg_stride; |
---|
71 | 123 | u32 irq_ports; |
---|
72 | 124 | u32 rdma_reg_base; |
---|
73 | 125 | u32 rdma_reg_stride; |
---|
74 | 126 | u32 rdma_channels; |
---|
| 127 | + u32 hdmi_rdma_reg_base; |
---|
| 128 | + u32 hdmi_rdma_reg_stride; |
---|
| 129 | + u32 hdmi_rdma_channels; |
---|
75 | 130 | u32 wrdma_reg_base; |
---|
76 | 131 | u32 wrdma_reg_stride; |
---|
77 | 132 | u32 wrdma_channels; |
---|
| 133 | + u32 i2sctrl_reg_base; |
---|
| 134 | + u32 i2sctrl_reg_stride; |
---|
| 135 | + u32 i2s_ports; |
---|
| 136 | + |
---|
| 137 | + /* I2SCTL Register fields */ |
---|
| 138 | + struct reg_field loopback; |
---|
| 139 | + struct reg_field spken; |
---|
| 140 | + struct reg_field spkmode; |
---|
| 141 | + struct reg_field spkmono; |
---|
| 142 | + struct reg_field micen; |
---|
| 143 | + struct reg_field micmode; |
---|
| 144 | + struct reg_field micmono; |
---|
| 145 | + struct reg_field wssrc; |
---|
| 146 | + struct reg_field bitwidth; |
---|
| 147 | + |
---|
| 148 | + u32 hdmi_irq_reg_base; |
---|
| 149 | + u32 hdmi_irq_reg_stride; |
---|
| 150 | + u32 hdmi_irq_ports; |
---|
| 151 | + |
---|
| 152 | + /* HDMI specific controls */ |
---|
| 153 | + u32 hdmi_tx_ctl_addr; |
---|
| 154 | + u32 hdmi_legacy_addr; |
---|
| 155 | + u32 hdmi_vbit_addr; |
---|
| 156 | + u32 hdmi_ch_lsb_addr; |
---|
| 157 | + u32 hdmi_ch_msb_addr; |
---|
| 158 | + u32 ch_stride; |
---|
| 159 | + u32 hdmi_parity_addr; |
---|
| 160 | + u32 hdmi_dmactl_addr; |
---|
| 161 | + u32 hdmi_dma_stride; |
---|
| 162 | + u32 hdmi_DP_addr; |
---|
| 163 | + u32 hdmi_sstream_addr; |
---|
| 164 | + |
---|
| 165 | + /* HDMI SSTREAM CTRL fields */ |
---|
| 166 | + struct reg_field sstream_en; |
---|
| 167 | + struct reg_field dma_sel; |
---|
| 168 | + struct reg_field auto_bbit_en; |
---|
| 169 | + struct reg_field layout; |
---|
| 170 | + struct reg_field layout_sp; |
---|
| 171 | + struct reg_field set_sp_on_en; |
---|
| 172 | + struct reg_field dp_audio; |
---|
| 173 | + struct reg_field dp_staffing_en; |
---|
| 174 | + struct reg_field dp_sp_b_hw_en; |
---|
| 175 | + |
---|
| 176 | + /* HDMI DP METADATA CTL fields */ |
---|
| 177 | + struct reg_field mute; |
---|
| 178 | + struct reg_field as_sdp_cc; |
---|
| 179 | + struct reg_field as_sdp_ct; |
---|
| 180 | + struct reg_field aif_db4; |
---|
| 181 | + struct reg_field frequency; |
---|
| 182 | + struct reg_field mst_index; |
---|
| 183 | + struct reg_field dptx_index; |
---|
| 184 | + |
---|
| 185 | + /* HDMI TX CTRL fields */ |
---|
| 186 | + struct reg_field soft_reset; |
---|
| 187 | + struct reg_field force_reset; |
---|
| 188 | + |
---|
| 189 | + /* HDMI TX DMA CTRL */ |
---|
| 190 | + struct reg_field use_hw_chs; |
---|
| 191 | + struct reg_field use_hw_usr; |
---|
| 192 | + struct reg_field hw_chs_sel; |
---|
| 193 | + struct reg_field hw_usr_sel; |
---|
| 194 | + |
---|
| 195 | + /* HDMI VBIT CTRL */ |
---|
| 196 | + struct reg_field replace_vbit; |
---|
| 197 | + struct reg_field vbit_stream; |
---|
| 198 | + |
---|
| 199 | + /* HDMI TX LEGACY */ |
---|
| 200 | + struct reg_field legacy_en; |
---|
| 201 | + |
---|
| 202 | + /* HDMI TX PARITY */ |
---|
| 203 | + struct reg_field calc_en; |
---|
| 204 | + |
---|
| 205 | + /* HDMI CH LSB */ |
---|
| 206 | + struct reg_field lsb_bits; |
---|
| 207 | + |
---|
| 208 | + /* HDMI CH MSB */ |
---|
| 209 | + struct reg_field msb_bits; |
---|
| 210 | + |
---|
| 211 | + struct reg_field hdmi_rdma_bursten; |
---|
| 212 | + struct reg_field hdmi_rdma_wpscnt; |
---|
| 213 | + struct reg_field hdmi_rdma_fifowm; |
---|
| 214 | + struct reg_field hdmi_rdma_enable; |
---|
| 215 | + struct reg_field hdmi_rdma_dyncclk; |
---|
| 216 | + struct reg_field hdmi_rdma_burst8; |
---|
| 217 | + struct reg_field hdmi_rdma_burst16; |
---|
| 218 | + struct reg_field hdmi_rdma_dynburst; |
---|
| 219 | + |
---|
| 220 | + /* RD_DMA Register fields */ |
---|
| 221 | + struct reg_field rdma_intf; |
---|
| 222 | + struct reg_field rdma_bursten; |
---|
| 223 | + struct reg_field rdma_wpscnt; |
---|
| 224 | + struct reg_field rdma_fifowm; |
---|
| 225 | + struct reg_field rdma_enable; |
---|
| 226 | + struct reg_field rdma_dyncclk; |
---|
| 227 | + |
---|
| 228 | + /* WR_DMA Register fields */ |
---|
| 229 | + struct reg_field wrdma_intf; |
---|
| 230 | + struct reg_field wrdma_bursten; |
---|
| 231 | + struct reg_field wrdma_wpscnt; |
---|
| 232 | + struct reg_field wrdma_fifowm; |
---|
| 233 | + struct reg_field wrdma_enable; |
---|
| 234 | + struct reg_field wrdma_dyncclk; |
---|
78 | 235 | |
---|
79 | 236 | /** |
---|
80 | 237 | * on SOCs like APQ8016 the channel control bits start |
---|
.. | .. |
---|
85 | 242 | /* SOC specific initialization like clocks */ |
---|
86 | 243 | int (*init)(struct platform_device *pdev); |
---|
87 | 244 | int (*exit)(struct platform_device *pdev); |
---|
88 | | - int (*alloc_dma_channel)(struct lpass_data *data, int direction); |
---|
89 | | - int (*free_dma_channel)(struct lpass_data *data, int ch); |
---|
| 245 | + int (*alloc_dma_channel)(struct lpass_data *data, int direction, unsigned int dai_id); |
---|
| 246 | + int (*free_dma_channel)(struct lpass_data *data, int ch, unsigned int dai_id); |
---|
90 | 247 | |
---|
91 | 248 | /* SOC specific dais */ |
---|
92 | 249 | struct snd_soc_dai_driver *dai_driver; |
---|
93 | 250 | int num_dai; |
---|
94 | 251 | const char * const *dai_osr_clk_names; |
---|
95 | 252 | const char * const *dai_bit_clk_names; |
---|
| 253 | + |
---|
| 254 | + /* SOC specific clocks configuration */ |
---|
| 255 | + const char **clk_name; |
---|
| 256 | + int num_clks; |
---|
96 | 257 | }; |
---|
97 | 258 | |
---|
98 | 259 | /* register the platform driver from the CPU DAI driver */ |
---|