You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.3 KiB
114 lines
4.3 KiB
/* |
|
* Copyright (c) 2024, Ambiq Micro Inc. <www.ambiq.com> |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#ifndef MSPI_AMBIQ_H_ |
|
#define MSPI_AMBIQ_H_ |
|
|
|
#include <soc.h> |
|
|
|
/* Hand-calculated minimum heap sizes needed to return a successful |
|
* 1-byte allocation. See details in lib/os/heap.[ch] |
|
*/ |
|
#define MSPI_AMBIQ_HEAP_MIN_SIZE (sizeof(void *) > 4 ? 56 : 44) |
|
|
|
#define MSPI_AMBIQ_HEAP_DEFINE(name, bytes) \ |
|
char __attribute__((section(".mspi_buff"))) \ |
|
kheap_##name[MAX(bytes, MSPI_AMBIQ_HEAP_MIN_SIZE)]; \ |
|
STRUCT_SECTION_ITERABLE(k_heap, name) = { \ |
|
.heap = \ |
|
{ \ |
|
.init_mem = kheap_##name, \ |
|
.init_bytes = MAX(bytes, MSPI_AMBIQ_HEAP_MIN_SIZE), \ |
|
}, \ |
|
} |
|
|
|
#define MSPI_CQ_MAX_ENTRY MSPI0_CQCURIDX_CQCURIDX_Msk |
|
|
|
enum mspi_ambiq_timing_param { |
|
MSPI_AMBIQ_SET_WLC = BIT(0), |
|
MSPI_AMBIQ_SET_RLC = BIT(1), |
|
MSPI_AMBIQ_SET_TXNEG = BIT(2), |
|
MSPI_AMBIQ_SET_RXNEG = BIT(3), |
|
MSPI_AMBIQ_SET_RXCAP = BIT(4), |
|
MSPI_AMBIQ_SET_TXDQSDLY = BIT(5), |
|
MSPI_AMBIQ_SET_RXDQSDLY = BIT(6), |
|
}; |
|
|
|
enum mspi_ambiq_timing_scan_type { |
|
MSPI_AMBIQ_TIMING_SCAN_MEMC = 0, |
|
MSPI_AMBIQ_TIMING_SCAN_FLASH, |
|
}; |
|
|
|
struct mspi_ambiq_timing_scan_range { |
|
int8_t rlc_start; |
|
int8_t rlc_end; |
|
int8_t txneg_start; |
|
int8_t txneg_end; |
|
int8_t rxneg_start; |
|
int8_t rxneg_end; |
|
int8_t rxcap_start; |
|
int8_t rxcap_end; |
|
int8_t txdqs_start; |
|
int8_t txdqs_end; |
|
int8_t rxdqs_start; |
|
int8_t rxdqs_end; |
|
}; |
|
|
|
struct mspi_ambiq_timing_cfg { |
|
uint8_t ui8WriteLatency; |
|
uint8_t ui8TurnAround; |
|
bool bTxNeg; |
|
bool bRxNeg; |
|
bool bRxCap; |
|
uint32_t ui32TxDQSDelay; |
|
uint32_t ui32RxDQSDelay; |
|
}; |
|
|
|
struct mspi_ambiq_timing_scan { |
|
struct mspi_ambiq_timing_scan_range range; |
|
enum mspi_ambiq_timing_scan_type scan_type; |
|
uint32_t min_window; |
|
uint32_t device_addr; |
|
struct mspi_ambiq_timing_cfg result; |
|
}; |
|
|
|
#define TIMING_CFG_GET_RX_DUMMY(cfg) \ |
|
{ \ |
|
mspi_timing_cfg *timing = (mspi_timing_cfg *)cfg; \ |
|
timing->ui8TurnAround; \ |
|
} |
|
|
|
#define TIMING_CFG_SET_RX_DUMMY(cfg, num) \ |
|
{ \ |
|
mspi_timing_cfg *timing = (mspi_timing_cfg *)cfg; \ |
|
timing->ui8TurnAround = num; \ |
|
} |
|
|
|
#define MSPI_AMBIQ_TIMING_CONFIG(n) \ |
|
{ \ |
|
.ui8WriteLatency = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 0), \ |
|
.ui8TurnAround = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 1), \ |
|
.bTxNeg = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 2), \ |
|
.bRxNeg = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 3), \ |
|
.bRxCap = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 4), \ |
|
.ui32TxDQSDelay = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 5), \ |
|
.ui32RxDQSDelay = DT_INST_PROP_BY_IDX(n, ambiq_timing_config, 6), \ |
|
} |
|
|
|
#define MSPI_AMBIQ_TIMING_CONFIG_MASK(n) DT_INST_PROP(n, ambiq_timing_config_mask) |
|
|
|
#define MSPI_AMBIQ_PORT(n) ((DT_REG_ADDR(DT_INST_BUS(n)) - MSPI0_BASE) / \ |
|
(MSPI1_BASE - MSPI0_BASE)) |
|
|
|
|
|
int mspi_ambiq_timing_scan(const struct device *dev, |
|
const struct device *bus, |
|
const struct mspi_dev_id *dev_id, |
|
uint32_t param_mask, |
|
struct mspi_ambiq_timing_cfg *timing, |
|
struct mspi_ambiq_timing_scan *scan); |
|
|
|
#endif
|
|
|