cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aio.h (10078B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Socionext UniPhier AIO ALSA driver.
      4 *
      5 * Copyright (c) 2016-2018 Socionext Inc.
      6 */
      7
      8#ifndef SND_UNIPHIER_AIO_H__
      9#define SND_UNIPHIER_AIO_H__
     10
     11#include <linux/spinlock.h>
     12#include <linux/types.h>
     13#include <sound/pcm.h>
     14#include <sound/soc.h>
     15#include <sound/soc-dai.h>
     16
     17struct platform_device;
     18
     19enum ID_PORT_TYPE {
     20	PORT_TYPE_UNKNOWN,
     21	PORT_TYPE_I2S,
     22	PORT_TYPE_SPDIF,
     23	PORT_TYPE_EVE,
     24	PORT_TYPE_CONV,
     25};
     26
     27enum ID_PORT_DIR {
     28	PORT_DIR_OUTPUT,
     29	PORT_DIR_INPUT,
     30};
     31
     32enum IEC61937_PC {
     33	IEC61937_PC_AC3   = 0x0001,
     34	IEC61937_PC_PAUSE = 0x0003,
     35	IEC61937_PC_MPA   = 0x0004,
     36	IEC61937_PC_MP3   = 0x0005,
     37	IEC61937_PC_DTS1  = 0x000b,
     38	IEC61937_PC_DTS2  = 0x000c,
     39	IEC61937_PC_DTS3  = 0x000d,
     40	IEC61937_PC_AAC   = 0x0007,
     41};
     42
     43/* IEC61937 Repetition period of data-burst in IEC60958 frames */
     44#define IEC61937_FRM_STR_AC3       1536
     45#define IEC61937_FRM_STR_MPA       1152
     46#define IEC61937_FRM_STR_MP3       1152
     47#define IEC61937_FRM_STR_DTS1      512
     48#define IEC61937_FRM_STR_DTS2      1024
     49#define IEC61937_FRM_STR_DTS3      2048
     50#define IEC61937_FRM_STR_AAC       1024
     51
     52/* IEC61937 Repetition period of Pause data-burst in IEC60958 frames */
     53#define IEC61937_FRM_PAU_AC3       3
     54#define IEC61937_FRM_PAU_MPA       32
     55#define IEC61937_FRM_PAU_MP3       32
     56#define IEC61937_FRM_PAU_DTS1      3
     57#define IEC61937_FRM_PAU_DTS2      3
     58#define IEC61937_FRM_PAU_DTS3      3
     59#define IEC61937_FRM_PAU_AAC       32
     60
     61/* IEC61937 Pa and Pb */
     62#define IEC61937_HEADER_SIGN       0x1f4e72f8
     63
     64#define AUD_HW_PCMIN1    0
     65#define AUD_HW_PCMIN2    1
     66#define AUD_HW_PCMIN3    2
     67#define AUD_HW_IECIN1    3
     68#define AUD_HW_DIECIN1   4
     69
     70#define AUD_NAME_PCMIN1     "aio-pcmin1"
     71#define AUD_NAME_PCMIN2     "aio-pcmin2"
     72#define AUD_NAME_PCMIN3     "aio-pcmin3"
     73#define AUD_NAME_IECIN1     "aio-iecin1"
     74#define AUD_NAME_DIECIN1    "aio-diecin1"
     75
     76#define AUD_HW_HPCMOUT1    0
     77#define AUD_HW_PCMOUT1     1
     78#define AUD_HW_PCMOUT2     2
     79#define AUD_HW_PCMOUT3     3
     80#define AUD_HW_EPCMOUT1    4
     81#define AUD_HW_EPCMOUT2    5
     82#define AUD_HW_EPCMOUT3    6
     83#define AUD_HW_EPCMOUT6    9
     84#define AUD_HW_HIECOUT1    10
     85#define AUD_HW_IECOUT1     11
     86#define AUD_HW_CMASTER     31
     87
     88#define AUD_NAME_HPCMOUT1        "aio-hpcmout1"
     89#define AUD_NAME_PCMOUT1         "aio-pcmout1"
     90#define AUD_NAME_PCMOUT2         "aio-pcmout2"
     91#define AUD_NAME_PCMOUT3         "aio-pcmout3"
     92#define AUD_NAME_EPCMOUT1        "aio-epcmout1"
     93#define AUD_NAME_EPCMOUT2        "aio-epcmout2"
     94#define AUD_NAME_EPCMOUT3        "aio-epcmout3"
     95#define AUD_NAME_EPCMOUT6        "aio-epcmout6"
     96#define AUD_NAME_HIECOUT1        "aio-hiecout1"
     97#define AUD_NAME_IECOUT1         "aio-iecout1"
     98#define AUD_NAME_CMASTER         "aio-cmaster"
     99#define AUD_NAME_HIECCOMPOUT1    "aio-hieccompout1"
    100#define AUD_NAME_IECCOMPOUT1     "aio-ieccompout1"
    101
    102#define AUD_GNAME_HDMI    "aio-hdmi"
    103#define AUD_GNAME_LINE    "aio-line"
    104#define AUD_GNAME_AUX     "aio-aux"
    105#define AUD_GNAME_IEC     "aio-iec"
    106
    107#define AUD_CLK_IO        0
    108#define AUD_CLK_A1        1
    109#define AUD_CLK_F1        2
    110#define AUD_CLK_A2        3
    111#define AUD_CLK_F2        4
    112#define AUD_CLK_A         5
    113#define AUD_CLK_F         6
    114#define AUD_CLK_APLL      7
    115#define AUD_CLK_RX0       8
    116#define AUD_CLK_USB0      9
    117#define AUD_CLK_HSC0      10
    118
    119#define AUD_PLL_A1        0
    120#define AUD_PLL_F1        1
    121#define AUD_PLL_A2        2
    122#define AUD_PLL_F2        3
    123#define AUD_PLL_APLL      4
    124#define AUD_PLL_RX0       5
    125#define AUD_PLL_USB0      6
    126#define AUD_PLL_HSC0      7
    127
    128#define AUD_PLLDIV_1_2    0
    129#define AUD_PLLDIV_1_3    1
    130#define AUD_PLLDIV_1_1    2
    131#define AUD_PLLDIV_2_3    3
    132
    133#define AUD_VOL_INIT         0x4000 /* +0dB */
    134#define AUD_VOL_MAX          0xffff /* +6dB */
    135#define AUD_VOL_FADE_TIME    20 /* 20ms */
    136
    137#define AUD_RING_SIZE            (128 * 1024)
    138
    139#define AUD_MIN_FRAGMENT         4
    140#define AUD_MAX_FRAGMENT         8
    141#define AUD_MIN_FRAGMENT_SIZE    (4 * 1024)
    142#define AUD_MAX_FRAGMENT_SIZE    (16 * 1024)
    143
    144/* max 5 slots, 10 channels, 2 channel in 1 slot */
    145#define AUD_MAX_SLOTSEL    5
    146
    147/*
    148 * This is a selector for virtual register map of AIO.
    149 *
    150 * map:  Specify the index of virtual register map.
    151 * hw :  Specify the ID of real register map, selector uses this value.
    152 *       A meaning of this value depends specification of SoC.
    153 */
    154struct uniphier_aio_selector {
    155	int map;
    156	int hw;
    157};
    158
    159/**
    160 * 'SoftWare MAPping' setting of UniPhier AIO registers.
    161 *
    162 * We have to setup 'virtual' register maps to access 'real' registers of AIO.
    163 * This feature is legacy and meaningless but AIO needs this to work.
    164 *
    165 * Each hardware blocks have own virtual register maps as following:
    166 *
    167 * Address Virtual                      Real
    168 * ------- ---------                    ---------------
    169 * 0x12000 DMAC map0 --> [selector] --> DMAC hardware 3
    170 * 0x12080 DMAC map1 --> [selector] --> DMAC hardware 1
    171 * ...
    172 * 0x42000 Port map0 --> [selector] --> Port hardware 1
    173 * 0x42400 Port map1 --> [selector] --> Port hardware 2
    174 * ...
    175 *
    176 * ch   : Input or output channel of DMAC
    177 * rb   : Ring buffer
    178 * iport: PCM input port
    179 * iif  : Input interface
    180 * oport: PCM output port
    181 * oif  : Output interface
    182 * och  : Output channel of DMAC for sampling rate converter
    183 *
    184 * These are examples for sound data paths:
    185 *
    186 * For caputure device:
    187 *   (outer of AIO) -> iport -> iif -> ch -> rb -> (CPU)
    188 * For playback device:
    189 *   (CPU) -> rb -> ch -> oif -> oport -> (outer of AIO)
    190 * For sampling rate converter device:
    191 *   (CPU) -> rb -> ch -> oif -> (HW SRC) -> iif -> och -> orb -> (CPU)
    192 */
    193struct uniphier_aio_swmap {
    194	int type;
    195	int dir;
    196
    197	struct uniphier_aio_selector ch;
    198	struct uniphier_aio_selector rb;
    199	struct uniphier_aio_selector iport;
    200	struct uniphier_aio_selector iif;
    201	struct uniphier_aio_selector oport;
    202	struct uniphier_aio_selector oif;
    203	struct uniphier_aio_selector och;
    204};
    205
    206struct uniphier_aio_spec {
    207	const char *name;
    208	const char *gname;
    209	struct uniphier_aio_swmap swm;
    210};
    211
    212struct uniphier_aio_pll {
    213	bool enable;
    214	unsigned int freq;
    215};
    216
    217struct uniphier_aio_chip_spec {
    218	const struct uniphier_aio_spec *specs;
    219	int num_specs;
    220	const struct uniphier_aio_pll *plls;
    221	int num_plls;
    222	struct snd_soc_dai_driver *dais;
    223	int num_dais;
    224
    225	/* DMA access mode, this is workaround for DMA hungup */
    226	int addr_ext;
    227};
    228
    229struct uniphier_aio_sub {
    230	struct uniphier_aio *aio;
    231
    232	/* Guard sub->rd_offs and wr_offs from IRQ handler. */
    233	spinlock_t lock;
    234
    235	const struct uniphier_aio_swmap *swm;
    236	const struct uniphier_aio_spec *spec;
    237
    238	/* For PCM audio */
    239	struct snd_pcm_substream *substream;
    240	struct snd_pcm_hw_params params;
    241	int vol;
    242
    243	/* For compress audio */
    244	struct snd_compr_stream *cstream;
    245	struct snd_compr_params cparams;
    246	unsigned char *compr_area;
    247	dma_addr_t compr_addr;
    248	size_t compr_bytes;
    249	int pass_through;
    250	enum IEC61937_PC iec_pc;
    251	bool iec_header;
    252
    253	/* Both PCM and compress audio */
    254	bool use_mmap;
    255	int setting;
    256	int running;
    257	u64 rd_offs;
    258	u64 wr_offs;
    259	u32 threshold;
    260	u64 rd_org;
    261	u64 wr_org;
    262	u64 rd_total;
    263	u64 wr_total;
    264};
    265
    266struct uniphier_aio {
    267	struct uniphier_aio_chip *chip;
    268
    269	struct uniphier_aio_sub sub[2];
    270
    271	unsigned int fmt;
    272	/* Set one of AUD_CLK_X */
    273	int clk_in;
    274	int clk_out;
    275	/* Set one of AUD_PLL_X */
    276	int pll_in;
    277	int pll_out;
    278	/* Set one of AUD_PLLDIV_X */
    279	int plldiv;
    280};
    281
    282struct uniphier_aio_chip {
    283	struct platform_device *pdev;
    284	const struct uniphier_aio_chip_spec *chip_spec;
    285
    286	struct uniphier_aio *aios;
    287	int num_aios;
    288	int num_wup_aios;
    289	struct uniphier_aio_pll *plls;
    290	int num_plls;
    291
    292	struct clk *clk;
    293	struct reset_control *rst;
    294	struct regmap *regmap;
    295	struct regmap *regmap_sg;
    296	int active;
    297};
    298
    299static inline struct uniphier_aio *uniphier_priv(struct snd_soc_dai *dai)
    300{
    301	struct uniphier_aio_chip *chip = snd_soc_dai_get_drvdata(dai);
    302
    303	return &chip->aios[dai->id];
    304}
    305
    306int uniphier_aiodma_soc_register_platform(struct platform_device *pdev);
    307extern const struct snd_compress_ops uniphier_aio_compress_ops;
    308
    309int uniphier_aio_dai_probe(struct snd_soc_dai *dai);
    310int uniphier_aio_dai_remove(struct snd_soc_dai *dai);
    311int uniphier_aio_probe(struct platform_device *pdev);
    312int uniphier_aio_remove(struct platform_device *pdev);
    313extern const struct snd_soc_dai_ops uniphier_aio_i2s_ops;
    314extern const struct snd_soc_dai_ops uniphier_aio_spdif_ops;
    315
    316u64 aio_rb_cnt(struct uniphier_aio_sub *sub);
    317u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub);
    318u64 aio_rb_space(struct uniphier_aio_sub *sub);
    319u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub);
    320
    321void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable);
    322int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
    323		     unsigned int freq);
    324void aio_chip_init(struct uniphier_aio_chip *chip);
    325int aio_init(struct uniphier_aio_sub *sub);
    326void aio_port_reset(struct uniphier_aio_sub *sub);
    327int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
    328		       const struct snd_pcm_hw_params *params);
    329void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable);
    330int aio_port_get_volume(struct uniphier_aio_sub *sub);
    331void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol);
    332int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through);
    333int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
    334			      enum IEC61937_PC pc);
    335void aio_src_reset(struct uniphier_aio_sub *sub);
    336int aio_src_set_param(struct uniphier_aio_sub *sub,
    337		      const struct snd_pcm_hw_params *params);
    338int aio_srcif_set_param(struct uniphier_aio_sub *sub);
    339int aio_srcch_set_param(struct uniphier_aio_sub *sub);
    340void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable);
    341
    342int aiodma_ch_set_param(struct uniphier_aio_sub *sub);
    343void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable);
    344int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th);
    345int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
    346			 int period);
    347void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
    348		    int period);
    349bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub);
    350void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub);
    351
    352#endif /* SND_UNIPHIER_AIO_H__ */