f764e7e737
Refcounting is used to track ALH block usage and to call alh_claim_ownership()/alh_release_ownership() accordingly. This is however incorrectly done on ALH instance basis, which means when one instance is released, ownership can be released even though one ALH instance is still active. Fix the logic by tracking ALH usage as a global property which matches the alh_claim_ownership/alh_release_ownership semantics. Link: https://github.com/thesofproject/sof/issues/7759 Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
121 lines
2.8 KiB
C
121 lines
2.8 KiB
C
/*
|
|
* Copyright (c) 2022 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef __INTEL_DAI_DRIVER_ALH_H__
|
|
#define __INTEL_DAI_DRIVER_ALH_H__
|
|
|
|
#include <stdint.h>
|
|
#include <zephyr/drivers/dai.h>
|
|
|
|
#include "alh_map.h"
|
|
|
|
#define DAI_NUM_ALH_BI_DIR_LINKS_GROUP 4
|
|
|
|
#define ALH_STREAM_OFFSET 0x4
|
|
|
|
#define IPC4_ALH_MAX_NUMBER_OF_GTW 16
|
|
#define IPC4_ALH_DAI_INDEX_OFFSET 7
|
|
|
|
/* copier id = (group id << 4) + codec id + IPC4_ALH_DAI_INDEX_OFFSET
|
|
* dai_index = (group id << 8) + codec id;
|
|
*/
|
|
#define IPC4_ALH_DAI_INDEX(x) ((((x) & 0xF0) << DAI_NUM_ALH_BI_DIR_LINKS_GROUP) + \
|
|
(((x) & 0xF) - IPC4_ALH_DAI_INDEX_OFFSET))
|
|
|
|
#define ALH_GPDMA_BURST_LENGTH 4
|
|
|
|
#define ALH_SET_BITS(b_hi, b_lo, x) \
|
|
(((x) & ((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL)) << (b_lo))
|
|
#define ALHASCTL_OSEL(x) ALH_SET_BITS(25, 24, x)
|
|
|
|
#define dai_get_drvdata(dai) &dai->priv_data
|
|
#define dai_base(dai) dai->plat_data.base
|
|
|
|
#define DAI_DIR_PLAYBACK 0
|
|
#define DAI_DIR_CAPTURE 1
|
|
|
|
#define ALH_CHANNELS_DEFAULT 2
|
|
#define ALH_RATE_DEFAULT 48000
|
|
#define ALH_WORD_SIZE_DEFAULT 32
|
|
|
|
#if CONFIG_INTEL_ADSP_CAVS
|
|
#define ALH_TXDA_OFFSET 0x400
|
|
#define ALH_RXDA_OFFSET 0x500
|
|
#else
|
|
#define ALH_TXDA_OFFSET 0
|
|
#define ALH_RXDA_OFFSET 0x100
|
|
#endif
|
|
|
|
union dai_intel_ipc4_gateway_attributes {
|
|
/**< Raw value */
|
|
uint32_t dw;
|
|
|
|
/**< Access to the fields */
|
|
struct {
|
|
/**< Gateway data requested in low power memory. */
|
|
uint32_t lp_buffer_alloc : 1;
|
|
|
|
/**< Gateway data requested in register file memory. */
|
|
uint32_t alloc_from_reg_file : 1;
|
|
|
|
/**< Reserved field */
|
|
uint32_t _rsvd : 30;
|
|
} bits; /**<< Bits */
|
|
} __packed;
|
|
|
|
/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
|
|
struct dai_intel_ipc3_alh_params {
|
|
uint32_t reserved0;
|
|
uint32_t stream_id;
|
|
uint32_t rate;
|
|
uint32_t channels;
|
|
|
|
/* reserved for future use */
|
|
uint32_t reserved[13];
|
|
} __packed;
|
|
|
|
struct ipc4_alh_multi_gtw_cfg {
|
|
/* Number of single channels (valid items in mapping array). */
|
|
uint32_t count;
|
|
/* Single to multi aggregation mapping item. */
|
|
struct {
|
|
/* Vindex of a single ALH channel aggregated. */
|
|
uint32_t alh_id;
|
|
/* Channel mask */
|
|
uint32_t channel_mask;
|
|
} mapping[IPC4_ALH_MAX_NUMBER_OF_GTW]; /* < Mapping items */
|
|
} __packed;
|
|
|
|
struct dai_intel_ipc4_alh_configuration_blob {
|
|
union dai_intel_ipc4_gateway_attributes gtw_attributes;
|
|
struct ipc4_alh_multi_gtw_cfg alh_cfg;
|
|
} __packed;
|
|
|
|
struct dai_intel_alh_plat_data {
|
|
uint32_t base;
|
|
uint32_t fifo_depth[2];
|
|
};
|
|
|
|
struct dai_intel_alh_pdata {
|
|
struct dai_config config;
|
|
struct dai_properties props;
|
|
struct dai_intel_ipc3_alh_params params;
|
|
};
|
|
|
|
struct dai_intel_alh {
|
|
uint32_t index; /**< index */
|
|
struct dai_intel_alh_plat_data plat_data;
|
|
struct dai_intel_alh_pdata priv_data;
|
|
};
|
|
|
|
/* Common data for all ALH DAI instances */
|
|
struct dai_alh_global_shared {
|
|
struct k_spinlock lock; /**< locking mechanism */
|
|
int sref; /**< simple ref counter, guarded by lock */
|
|
};
|
|
|
|
#endif
|