Update Annapurna Alpine HAL to a newer version.

HAL version: 2.7a

Import from vendor-sys, r305475
This commit is contained in:
Wojciech Macek 2016-09-06 14:59:13 +00:00
commit 3fc36ee018
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305477
89 changed files with 64037 additions and 3540 deletions

View File

@ -129,10 +129,10 @@ int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
}
/*
* configure the vmid attributes for a given msix vector.
* configure the target-id attributes for a given msix vector.
*/
int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t vmid, uint8_t vmid_en)
int al_iofic_msix_tgtid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t tgtid, uint8_t tgtid_en)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg = 0;
@ -141,14 +141,14 @@ int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
al_assert(group < AL_IOFIC_MAX_GROUPS);
AL_REG_FIELD_SET(reg,
INT_MSIX_VMID_MASK,
INT_MSIX_VMID_SHIFT,
vmid);
INT_MSIX_TGTID_MASK,
INT_MSIX_TGTID_SHIFT,
tgtid);
AL_REG_BIT_VAL_SET(reg,
INT_MSIX_VMID_EN_SHIFT,
vmid_en);
INT_MSIX_TGTID_EN_SHIFT,
tgtid_en);
al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_vmid_reg, reg);
al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_tgtid_reg, reg);
return 0;
}

View File

@ -117,17 +117,17 @@ int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
uint8_t vector, uint8_t interval);
/**
* configure the vmid attributes for a given msix vector.
* configure the tgtid attributes for a given msix vector.
*
* @param group the interrupt group
* @param vector index
* @param vmid the vmid value
* @param vmid_en take vmid from the intc
* @param tgtid the target-id value
* @param tgtid_en take target-id from the intc
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t vmid, uint8_t vmid_en);
int al_iofic_msix_tgtid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t tgtid, uint8_t tgtid_en);
/**
* return the offset of the unmask register for a given group.

View File

@ -66,7 +66,7 @@ struct al_iofic_grp_ctrl {
struct al_iofic_grp_mod {
uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */
uint32_t grp_int_vmid_reg;
uint32_t grp_int_tgtid_reg;
};
struct al_iofic_regs {
@ -109,12 +109,12 @@ struct al_iofic_regs {
#define INT_MOD_INTV_MASK 0x000000FF
#define INT_MOD_INTV_SHIFT 0
/**** grp_int_vmid_reg register ****/
/* Interrupt vmid value registerDedicated reg ... */
#define INT_MSIX_VMID_MASK 0x0000FFFF
#define INT_MSIX_VMID_SHIFT 0
/* Interrupt vmid_en value registerDedicated reg ... */
#define INT_MSIX_VMID_EN_SHIFT 31
/**** grp_int_tgtid_reg register ****/
/* Interrupt tgtid value registerDedicated reg ... */
#define INT_MSIX_TGTID_MASK 0x0000FFFF
#define INT_MSIX_TGTID_SHIFT 0
/* Interrupt tgtid_en value registerDedicated reg ... */
#define INT_MSIX_TGTID_EN_SHIFT 31
#ifdef __cplusplus
}

View File

@ -355,7 +355,7 @@ struct al_nb_nb_version {
};
struct al_nb_sriov {
/* [0x0] */
uint32_t cpu_vmid[4];
uint32_t cpu_tgtid[4];
uint32_t rsrvd[4];
};
struct al_nb_dram_channels {
@ -403,7 +403,7 @@ struct al_nb_push_packet {
uint32_t pp_config;
uint32_t rsrvd_0[3];
/* [0x10] */
uint32_t pp_ext_awuser;
uint32_t pp_ext_attr;
uint32_t rsrvd_1[3];
/* [0x20] */
uint32_t pp_base_low;
@ -411,7 +411,7 @@ struct al_nb_push_packet {
uint32_t pp_base_high;
uint32_t rsrvd_2[2];
/* [0x30] */
uint32_t pp_sel_awuser;
uint32_t pp_sel_attr;
uint32_t rsrvd[51];
};
@ -853,8 +853,8 @@ Enables 4k hazard of post-barrier vs pre-barrier transactions. Otherwise, 64B ha
This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset. */
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_SHIFT 0
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_PKR 0x00000FFF
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_PKR 0
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_ALPINE_V2 0x00000FFF
#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_ALPINE_V2 0
/* GIC registers base [31:15].
This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset */
#define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000
@ -1055,9 +1055,9 @@ Other access types are hazard check against the pre-barrier requests. */
/* Disable counter (wait 1000 NB cycles) before applying PoS enable/disable configuration */
#define NB_GLOBAL_ACF_MISC_POS_CONFIG_CNT_DIS (1 << 14)
/* Disable wr spliter A0 bug fixes */
#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_M0_MODE (1 << 16)
/* Disable wr spliter PKR bug fixes */
#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_A0_MODE (1 << 17)
#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_V1_M0_MODE (1 << 16)
/* Disable wr spliter ALPINE_V2 bug fixes */
#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_V1_A0_MODE (1 << 17)
/* Override the address parity calucation for write transactions going to IO-fabric */
#define NB_GLOBAL_ACF_MISC_NB_NIC_AWADDR_PAR_OVRD (1 << 18)
/* Override the data parity calucation for write transactions going to IO-fabric */
@ -1074,7 +1074,7 @@ Other access types are hazard check against the pre-barrier requests. */
#define NB_GLOBAL_ACF_MISC_CPU_DSB_FLUSH_DIS (1 << 26)
/* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */
#define NB_GLOBAL_ACF_MISC_CPU_DMB_FLUSH_DIS (1 << 27)
/* Peakrock only: remap CPU address above 40 bits to Slave Error
/* Alpine V2 only: remap CPU address above 40 bits to Slave Error
INTERNAL */
#define NB_GLOBAL_ACF_MISC_ADDR43_40_REMAP_DIS (1 << 28)
/* Enable CPU WriteUnique to WriteNoSnoop trasform */
@ -1586,7 +1586,7 @@ enable - 0x1: Enable interrupt on overflow. */
/* Number of monitored events supported by the PMU. */
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_MASK 0x00FC0000
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT 18
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE 19
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE_V1 19
/* Number of counters implemented by PMU. */
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_MASK 0x0F000000
#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_SHIFT 24
@ -1659,6 +1659,9 @@ Note: This field must be changed for larger counters. */
/* Revision number (Major) */
#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V1 2
#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V2 3
#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_VAL_ALPINE_V3 4
/* Date of release */
#define NB_NB_VERSION_VERSION_DATE_DAY_MASK 0x001F0000
#define NB_NB_VERSION_VERSION_DATE_DAY_SHIFT 16
@ -1672,10 +1675,10 @@ Note: This field must be changed for larger counters. */
#define NB_NB_VERSION_VERSION_RESERVED_MASK 0xC0000000
#define NB_NB_VERSION_VERSION_RESERVED_SHIFT 30
/**** cpu_vmid register ****/
/* Target VMID */
#define NB_SRIOV_CPU_VMID_VAL_MASK 0x000000FF
#define NB_SRIOV_CPU_VMID_VAL_SHIFT 0
/**** cpu_tgtid register ****/
/* Target-ID */
#define NB_SRIOV_CPU_TGTID_VAL_MASK 0x000000FF
#define NB_SRIOV_CPU_TGTID_VAL_SHIFT 0
/**** DRAM_0_Control register ****/
/* Controller Idle
@ -1807,7 +1810,7 @@ Parity bits are still generated per transaction */
#define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_SHIFT 0
/**** pp_sel_awuser register ****/
/* Select whether to use addr[63:48] or PP awmisc as vmid.
/* Select whether to use addr[63:48] or PP awmisc as tgtid.
Each bit if set to 1 selects the corresponding address bit. Otherwise, selects the corersponding awmis bit. */
#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_MASK 0x0000FFFF
#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_SHIFT 0

View File

@ -447,11 +447,12 @@ struct al_pbs_target_id_enforcement {
};
struct al_pbs_regs {
struct al_pbs_unit unit; /* [0x0] */
struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
/* [0x250] */
uint32_t rsrvd_0[88];
struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */
struct al_pbs_unit unit; /* [0x0] */
struct al_pbs_low_latency_sram_remap low_latency_sram_remap; /* [0x250] */
uint32_t rsrvd_0[24];
uint32_t iofic_base; /* [0x300] */
uint32_t rsrvd_1[63];
struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */
};
@ -849,50 +850,50 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
* 2'b01 - select pcie_b[0]
* 2'b10 - select pcie_a[2]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_SHIFT 0
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_2_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_2_SHIFT 0
/*
* 2'b01 - select pcie_b[1]
* 2'b10 - select pcie_a[3]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_SHIFT 4
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_3_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_3_SHIFT 4
/*
* 2'b01 - select pcie_b[0]
* 2'b10 - select pcie_a[4]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_SHIFT 8
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_4_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_4_SHIFT 8
/*
* 2'b01 - select pcie_b[1]
* 2'b10 - select pcie_a[5]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_SHIFT 12
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_5_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_5_SHIFT 12
/*
* 2'b01 - select pcie_b[2]
* 2'b10 - select pcie_a[6]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_SHIFT 16
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_6_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_6_SHIFT 16
/*
* 2'b01 - select pcie_b[3]
* 2'b10 - select pcie_a[7]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_MASK 0x00300000
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_SHIFT 20
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_7_MASK 0x00300000
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_7_SHIFT 20
/*
* 2'b01 - select pcie_d[0]
* 2'b10 - select pcie_c[2]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_MASK 0x03000000
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_SHIFT 24
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_10_MASK 0x03000000
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_10_SHIFT 24
/*
* 2'b01 - select pcie_d[1]
* 2'b10 - select pcie_c[3]
*/
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_MASK 0x30000000
#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_SHIFT 28
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_11_MASK 0x30000000
#define PBS_UNIT_SERDES_MUX_PIPE_ALPINE_V2_SELECT_OH_SERDES_11_SHIFT 28
/**** dma_io_master_map register ****/
/*
@ -978,6 +979,14 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_MASK 0x3C000000
#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_SHIFT 26
/**** cfg_axi_conf_3 register ****/
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_LOW_MASK 0xFFFF
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_LOW_SHIFT 0
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_HI_MASK 0xFF0000
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_HI_SHIFT 16
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_SPI_HI_MASK 0xFF000000
#define PBS_UNIT_CFG_AXI_CONF_3_TIMEOUT_SPI_HI_SHIFT 24
/**** spi_mst_conf_0 register ****/
/*
* Sets the SPI master Configuration. For details see the SPI section in the
@ -1137,9 +1146,9 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
#define PBS_UNIT_CHIP_ID_DEV_ID_MASK 0xFFFF0000
#define PBS_UNIT_CHIP_ID_DEV_ID_SHIFT 16
#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE 0
#define PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK 1
#define PBS_UNIT_CHIP_ID_DEV_ID_COYOTE 2
#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V1 0
#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V2 1
#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V3 2
/**** uart0_conf_status register ****/
/*
@ -1420,56 +1429,56 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
* 2'b01 - select sata_b[0]
* 2'b10 - select eth_a[0]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_SHIFT 0
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_8_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_8_SHIFT 0
/*
* 3'b001 - select sata_b[1]
* 3'b010 - select eth_b[0]
* 3'b100 - select eth_a[1]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_MASK 0x00000070
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_SHIFT 4
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_9_MASK 0x00000070
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_9_SHIFT 4
/*
* 3'b001 - select sata_b[2]
* 3'b010 - select eth_c[0]
* 3'b100 - select eth_a[2]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_MASK 0x00000700
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_SHIFT 8
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_10_MASK 0x00000700
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_10_SHIFT 8
/*
* 3'b001 - select sata_b[3]
* 3'b010 - select eth_d[0]
* 3'b100 - select eth_a[3]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_MASK 0x00007000
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_SHIFT 12
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_11_MASK 0x00007000
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_11_SHIFT 12
/*
* 2'b01 - select eth_a[0]
* 2'b10 - select sata_a[0]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_SHIFT 16
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_12_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_12_SHIFT 16
/*
* 3'b001 - select eth_b[0]
* 3'b010 - select eth_c[1]
* 3'b100 - select sata_a[1]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_MASK 0x00700000
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_SHIFT 20
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_13_MASK 0x00700000
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_13_SHIFT 20
/*
* 3'b001 - select eth_a[0]
* 3'b010 - select eth_c[2]
* 3'b100 - select sata_a[2]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_MASK 0x07000000
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_SHIFT 24
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_14_MASK 0x07000000
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_14_SHIFT 24
/*
* 3'b001 - select eth_d[0]
* 3'b010 - select eth_c[3]
* 3'b100 - select sata_a[3]
*/
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_MASK 0x70000000
#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_SHIFT 28
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_15_MASK 0x70000000
#define PBS_UNIT_SERDES_MUX_MULTI_0_ALPINE_V2_SELECT_OH_SERDES_15_SHIFT 28
/**** serdes_mux_multi_1 register ****/
/* SerDes one hot mux control. For details see datasheet. */
@ -1632,62 +1641,62 @@ struct al_pbs_low_latency_sram_remap low_latency_sram_remap;
* 2'b01 - eth_a[0] from serdes_8
* 2'b10 - eth_a[0] from serdes_14
*/
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_SHIFT 0
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_0_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_0_SHIFT 0
/*
* 2'b01 - eth_b[0] from serdes_9
* 2'b10 - eth_b[0] from serdes_13
*/
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_SHIFT 4
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_B_0_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_B_0_SHIFT 4
/*
* 2'b01 - eth_c[0] from serdes_10
* 2'b10 - eth_c[0] from serdes_12
*/
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_SHIFT 8
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_0_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_0_SHIFT 8
/*
* 2'b01 - eth_d[0] from serdes_11
* 2'b10 - eth_d[0] from serdes_15
*/
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_SHIFT 12
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_D_0_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_D_0_SHIFT 12
/* which lane's is master clk */
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16
/* which lane's is master clk */
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20
/* enable xlaui on eth a */
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24)
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24)
/* enable xlaui on eth c */
#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28)
#define PBS_UNIT_SERDES_MUX_ETH_ALPINE_V2_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28)
/**** serdes_mux_pcie register ****/
/*
* 2'b01 - select pcie_b[0] from serdes 2
* 2'b10 - select pcie_b[0] from serdes 4
*/
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_SHIFT 0
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_0_MASK 0x00000003
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_0_SHIFT 0
/*
* 2'b01 - select pcie_b[1] from serdes 3
* 2'b10 - select pcie_b[1] from serdes 5
*/
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_SHIFT 4
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_1_MASK 0x00000030
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_B_1_SHIFT 4
/*
* 2'b01 - select pcie_d[0] from serdes 10
* 2'b10 - select pcie_d[0] from serdes 12
*/
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_SHIFT 8
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_0_MASK 0x00000300
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_0_SHIFT 8
/*
* 2'b01 - select pcie_d[1] from serdes 11
* 2'b10 - select pcie_d[1] from serdes 13
*/
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_SHIFT 12
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_1_MASK 0x00003000
#define PBS_UNIT_SERDES_MUX_PCIE_ALPINE_V2_SELECT_OH_PCIE_D_1_SHIFT 12
/**** serdes_mux_sata register ****/
/*

View File

@ -96,6 +96,8 @@ __FBSDID("$FreeBSD$");
#define AL_PCIE_PARSE_LANES(v) (((1 << v) - 1) << \
PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT)
#define AL_PCIE_FLR_DONE_INTERVAL 10
/**
* Static functions
*/
@ -183,10 +185,6 @@ al_pcie_port_link_config(
return -EINVAL;
}
al_dbg("PCIe %d: link config: max speed gen %d, max lanes %d, reversal %s\n",
pcie_port->port_id, link_params->max_speed,
pcie_port->max_lanes, link_params->enable_reversal? "enable" : "disable");
al_pcie_port_link_speed_ctrl_set(pcie_port, link_params->max_speed);
/* Change Max Payload Size, if needed.
@ -220,12 +218,6 @@ al_pcie_port_link_config(
(max_lanes + (max_lanes-1))
<< PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT);
/* TODO: add support for reversal mode */
if (link_params->enable_reversal) {
al_err("PCIe %d: enabling reversal mode not implemented\n",
pcie_port->port_id);
return -ENOSYS;
}
return 0;
}
@ -364,12 +356,9 @@ al_pcie_rev_id_get(
PBS_UNIT_CHIP_ID_DEV_ID_MASK,
PBS_UNIT_CHIP_ID_DEV_ID_SHIFT);
if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE) {
rev_id = AL_REG_FIELD_GET(
chip_id,
PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK,
PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT);
} else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK) {
if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V1) {
rev_id = AL_PCIE_REV_ID_1;
} else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE_V2) {
struct al_pcie_revx_regs __iomem *regs =
(struct al_pcie_revx_regs __iomem *)pcie_reg_base;
uint32_t dev_id;
@ -469,20 +458,6 @@ al_pcie_ib_hcrd_os_ob_reads_config_default(
al_pcie_port_ib_hcrd_os_ob_reads_config(pcie_port, &ib_hcrd_os_ob_reads_config);
};
/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */
static al_bool
al_pcie_is_link_started(struct al_pcie_port *pcie_port)
{
struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init);
uint8_t ltssm_en = AL_REG_FIELD_GET(port_init,
PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK,
PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT);
return ltssm_en;
}
/** return AL_TRUE if link is up, AL_FALSE otherwise */
static al_bool
al_pcie_check_link(
@ -650,18 +625,6 @@ al_pcie_port_gen3_params_config(struct al_pcie_port *pcie_port,
return 0;
}
static int
al_pcie_port_tl_credits_config(
struct al_pcie_port *pcie_port,
const struct al_pcie_tl_credits_params *tl_credits __attribute__((__unused__)))
{
al_err("PCIe %d: transport layer credits config not implemented\n",
pcie_port->port_id);
return -ENOSYS;
}
static int
al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
const struct al_pcie_pf_config_params *pf_params)
@ -680,22 +643,21 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
regs->core_space[pf_num].pcie_pm_cap_base,
AL_FIELD_MASK(26, 25) | AL_FIELD_MASK(31, 28), 0);
/* Disable FLR capability */
/* Set/Clear FLR bit */
if (pf_params->cap_flr_dis)
al_reg_write32_masked(
regs->core_space[pf_num].pcie_dev_cap_base,
AL_BIT(28), 0);
AL_PCI_EXP_DEVCAP_FLR, 0);
else
al_reg_write32_masked(
regs->core_space[pcie_pf->pf_num].pcie_dev_cap_base,
AL_PCI_EXP_DEVCAP_FLR, AL_PCI_EXP_DEVCAP_FLR);
/* Disable ASPM capability */
if (pf_params->cap_aspm_dis) {
al_reg_write32_masked(
regs->core_space[pf_num].pcie_cap_base + (AL_PCI_EXP_LNKCAP >> 2),
AL_PCI_EXP_LNKCAP_ASPMS, 0);
} else if (pcie_port->rev_id == AL_PCIE_REV_ID_0) {
al_warn("%s: ASPM support is enabled, please disable it\n",
__func__);
ret = -EINVAL;
goto done;
}
if (!pf_params->bar_params_valid) {
@ -743,8 +705,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
if (params->memory_space) {
if (size < AL_PCIE_MIN_MEMORY_BAR_SIZE) {
al_err("PCIe %d: memory BAR %d: size (0x%llx) less that minimal allowed value\n",
pcie_port->port_id, bar_idx, size);
al_err("PCIe %d: memory BAR %d: size (0x%jx) less that minimal allowed value\n",
pcie_port->port_id, bar_idx,
(uintmax_t)size);
ret = -EINVAL;
goto done;
}
@ -756,8 +719,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
}
if (size < AL_PCIE_MIN_IO_BAR_SIZE) {
al_err("PCIe %d: IO BAR %d: size (0x%llx) less that minimal allowed value\n",
pcie_port->port_id, bar_idx, size);
al_err("PCIe %d: IO BAR %d: size (0x%jx) less that minimal allowed value\n",
pcie_port->port_id, bar_idx,
(uintmax_t)size);
ret = -EINVAL;
goto done;
}
@ -765,9 +729,9 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
/* size must be power of 2 */
if (size & (size - 1)) {
al_err("PCIe %d: BAR %d:size (0x%llx) must be "
al_err("PCIe %d: BAR %d:size (0x%jx) must be "
"power of 2\n",
pcie_port->port_id, bar_idx, size);
pcie_port->port_id, bar_idx, (uintmax_t)size);
ret = -EINVAL;
goto done;
}
@ -826,8 +790,7 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
}
/* Open CPU generated msi and legacy interrupts in pcie wrapper logic */
if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_1)) {
if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_0, (1 << 21));
} else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
@ -853,13 +816,7 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
* Restore the original value after the write to app.soc.mask_msi_leg_0
* register.
*/
if (pcie_port->rev_id == AL_PCIE_REV_ID_0) {
uint32_t backup;
backup = al_reg_read32(&regs->app.int_grp_a->mask);
al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22));
al_reg_write32(&regs->app.int_grp_a->mask, backup);
} else if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22));
} else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
@ -878,22 +835,6 @@ al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf,
return ret;
}
static void
al_pcie_port_features_config(
struct al_pcie_port *pcie_port,
const struct al_pcie_features *features)
{
struct al_pcie_regs *regs = pcie_port->regs;
al_assert(pcie_port->rev_id > AL_PCIE_REV_ID_0);
al_reg_write32_masked(
&regs->app.ctrl_gen->features,
PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX,
features->sata_ep_msi_fix ?
PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX : 0);
}
static int
al_pcie_port_sris_config(
struct al_pcie_port *pcie_port,
@ -916,6 +857,9 @@ al_pcie_port_sris_config(
switch (pcie_port->rev_id) {
case AL_PCIE_REV_ID_3:
al_reg_write32_masked(&regs->app.cfg_func_ext->cfg,
PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE,
PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE);
case AL_PCIE_REV_ID_2:
al_reg_write32_masked(regs->app.global_ctrl.sris_kp_counter,
PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK |
@ -989,6 +933,34 @@ al_pcie_port_max_num_of_pfs_get(struct al_pcie_port *pcie_port)
return 1;
}
/** Enable ecrc generation in outbound atu (Addressing RMN: 5119) */
static void al_pcie_ecrc_gen_ob_atu_enable(struct al_pcie_port *pcie_port, unsigned int pf_num)
{
struct al_pcie_regs *regs = pcie_port->regs;
int max_ob_atu = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
AL_PCIE_REV_3_ATU_NUM_OUTBOUND_REGIONS : AL_PCIE_REV_1_2_ATU_NUM_OUTBOUND_REGIONS;
int i;
for (i = 0; i < max_ob_atu; i++) {
al_bool enable = 0;
uint32_t reg = 0;
unsigned int func_num;
AL_REG_FIELD_SET(reg, 0xF, 0, i);
AL_REG_BIT_VAL_SET(reg, 31, AL_PCIE_ATU_DIR_OUTBOUND);
al_reg_write32(&regs->port_regs->iatu.index, reg);
reg = al_reg_read32(&regs->port_regs->iatu.cr2);
enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE;
reg = al_reg_read32(&regs->port_regs->iatu.cr1);
func_num = AL_REG_FIELD_GET(reg,
PCIE_IATU_CR1_FUNC_NUM_MASK,
PCIE_IATU_CR1_FUNC_NUM_SHIFT);
if ((enable == AL_TRUE) && (pf_num == func_num)) {
/* Set TD bit */
AL_REG_BIT_SET(reg, 8);
al_reg_write32(&regs->port_regs->iatu.cr1, reg);
}
}
}
/******************************************************************************/
/***************************** API Implementation *****************************/
/******************************************************************************/
@ -1025,12 +997,13 @@ al_pcie_port_handle_init(
/* Zero all regs */
al_memset(pcie_port->regs, 0, sizeof(struct al_pcie_regs));
if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_1)) {
if (pcie_port->rev_id == AL_PCIE_REV_ID_1) {
struct al_pcie_rev1_regs __iomem *regs =
(struct al_pcie_rev1_regs __iomem *)pcie_reg_base;
pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
@ -1059,20 +1032,21 @@ al_pcie_port_handle_init(
pcie_port->regs->app.global_ctrl.pm_control = &regs->app.global_ctrl.pm_control;
pcie_port->regs->app.global_ctrl.events_gen[0] = &regs->app.global_ctrl.events_gen;
pcie_port->regs->app.debug = &regs->app.debug;
pcie_port->regs->app.soc_int[0].status_0 = &regs->app.soc_int.status_0;
pcie_port->regs->app.soc_int[0].status_1 = &regs->app.soc_int.status_1;
pcie_port->regs->app.soc_int[0].status_2 = &regs->app.soc_int.status_2;
pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = &regs->app.soc_int.mask_inta_leg_0;
pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = &regs->app.soc_int.mask_inta_leg_1;
pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = &regs->app.soc_int.mask_inta_leg_2;
pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = &regs->app.soc_int.mask_msi_leg_0;
pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = &regs->app.soc_int.mask_msi_leg_1;
pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = &regs->app.soc_int.mask_msi_leg_2;
pcie_port->regs->app.ctrl_gen = &regs->app.ctrl_gen;
pcie_port->regs->app.parity = &regs->app.parity;
pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair;
pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair;
if (pcie_port->rev_id == AL_PCIE_REV_ID_0) {
pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a_m0;
pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b_m0;
} else {
pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a;
pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b;
}
pcie_port->regs->app.int_grp_a = &regs->app.int_grp_a;
pcie_port->regs->app.int_grp_b = &regs->app.int_grp_b;
pcie_port->regs->core_space[0].config_header = regs->core_space.config_header;
pcie_port->regs->core_space[0].pcie_pm_cap_base = &regs->core_space.pcie_pm_cap_base;
@ -1091,6 +1065,8 @@ al_pcie_port_handle_init(
(struct al_pcie_rev2_regs __iomem *)pcie_reg_base;
pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
@ -1100,6 +1076,10 @@ al_pcie_port_handle_init(
pcie_port->regs->axi.ob_ctrl.io_start_h = &regs->axi.ob_ctrl.io_start_h;
pcie_port->regs->axi.ob_ctrl.io_limit_l = &regs->axi.ob_ctrl.io_limit_l;
pcie_port->regs->axi.ob_ctrl.io_limit_h = &regs->axi.ob_ctrl.io_limit_h;
pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = &regs->axi.ob_ctrl.tgtid_reg_ovrd;
pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = &regs->axi.ob_ctrl.addr_high_reg_ovrd_sel;
pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = &regs->axi.ob_ctrl.addr_high_reg_ovrd_value;
pcie_port->regs->axi.ob_ctrl.addr_size_replace = &regs->axi.ob_ctrl.addr_size_replace;
pcie_port->regs->axi.pcie_global.conf = &regs->axi.pcie_global.conf;
pcie_port->regs->axi.conf.zero_lane0 = &regs->axi.conf.zero_lane0;
pcie_port->regs->axi.conf.zero_lane1 = &regs->axi.conf.zero_lane1;
@ -1120,11 +1100,20 @@ al_pcie_port_handle_init(
pcie_port->regs->app.global_ctrl.events_gen[0] = &regs->app.global_ctrl.events_gen;
pcie_port->regs->app.global_ctrl.corr_err_sts_int = &regs->app.global_ctrl.pended_corr_err_sts_int;
pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = &regs->app.global_ctrl.pended_uncorr_err_sts_int;
pcie_port->regs->app.global_ctrl.sris_kp_counter = &regs->app.global_ctrl.sris_kp_counter_value;
pcie_port->regs->app.debug = &regs->app.debug;
pcie_port->regs->app.ap_user_send_msg = &regs->app.ap_user_send_msg;
pcie_port->regs->app.soc_int[0].status_0 = &regs->app.soc_int.status_0;
pcie_port->regs->app.soc_int[0].status_1 = &regs->app.soc_int.status_1;
pcie_port->regs->app.soc_int[0].status_2 = &regs->app.soc_int.status_2;
pcie_port->regs->app.soc_int[0].status_3 = &regs->app.soc_int.status_3;
pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = &regs->app.soc_int.mask_inta_leg_0;
pcie_port->regs->app.soc_int[0].mask_inta_leg_1 = &regs->app.soc_int.mask_inta_leg_1;
pcie_port->regs->app.soc_int[0].mask_inta_leg_2 = &regs->app.soc_int.mask_inta_leg_2;
pcie_port->regs->app.soc_int[0].mask_inta_leg_3 = &regs->app.soc_int.mask_inta_leg_3;
pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = &regs->app.soc_int.mask_msi_leg_0;
pcie_port->regs->app.soc_int[0].mask_msi_leg_1 = &regs->app.soc_int.mask_msi_leg_1;
pcie_port->regs->app.soc_int[0].mask_msi_leg_2 = &regs->app.soc_int.mask_msi_leg_2;
pcie_port->regs->app.soc_int[0].mask_msi_leg_3 = &regs->app.soc_int.mask_msi_leg_3;
pcie_port->regs->app.ctrl_gen = &regs->app.ctrl_gen;
pcie_port->regs->app.parity = &regs->app.parity;
@ -1150,6 +1139,8 @@ al_pcie_port_handle_init(
struct al_pcie_rev3_regs __iomem *regs =
(struct al_pcie_rev3_regs __iomem *)pcie_reg_base;
pcie_port->regs->axi.ctrl.global = &regs->axi.ctrl.global;
pcie_port->regs->axi.ctrl.master_rctl = &regs->axi.ctrl.master_rctl;
pcie_port->regs->axi.ctrl.master_ctl = &regs->axi.ctrl.master_ctl;
pcie_port->regs->axi.ctrl.master_arctl = &regs->axi.ctrl.master_arctl;
pcie_port->regs->axi.ctrl.master_awctl = &regs->axi.ctrl.master_awctl;
pcie_port->regs->axi.ctrl.slv_ctl = &regs->axi.ctrl.slv_ctl;
@ -1159,6 +1150,13 @@ al_pcie_port_handle_init(
pcie_port->regs->axi.ob_ctrl.io_start_h = &regs->axi.ob_ctrl.io_start_h;
pcie_port->regs->axi.ob_ctrl.io_limit_l = &regs->axi.ob_ctrl.io_limit_l;
pcie_port->regs->axi.ob_ctrl.io_limit_h = &regs->axi.ob_ctrl.io_limit_h;
pcie_port->regs->axi.ob_ctrl.io_addr_mask_h = &regs->axi.ob_ctrl.io_addr_mask_h;
pcie_port->regs->axi.ob_ctrl.ar_msg_addr_mask_h = &regs->axi.ob_ctrl.ar_msg_addr_mask_h;
pcie_port->regs->axi.ob_ctrl.aw_msg_addr_mask_h = &regs->axi.ob_ctrl.aw_msg_addr_mask_h;
pcie_port->regs->axi.ob_ctrl.tgtid_reg_ovrd = &regs->axi.ob_ctrl.tgtid_reg_ovrd;
pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_sel = &regs->axi.ob_ctrl.addr_high_reg_ovrd_sel;
pcie_port->regs->axi.ob_ctrl.addr_high_reg_ovrd_value = &regs->axi.ob_ctrl.addr_high_reg_ovrd_value;
pcie_port->regs->axi.ob_ctrl.addr_size_replace = &regs->axi.ob_ctrl.addr_size_replace;
pcie_port->regs->axi.pcie_global.conf = &regs->axi.pcie_global.conf;
pcie_port->regs->axi.conf.zero_lane0 = &regs->axi.conf.zero_lane0;
pcie_port->regs->axi.conf.zero_lane1 = &regs->axi.conf.zero_lane1;
@ -1213,9 +1211,17 @@ al_pcie_port_handle_init(
pcie_port->regs->app.debug = &regs->app.debug;
for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
pcie_port->regs->app.soc_int[i].status_0 = &regs->app.soc_int_per_func[i].status_0;
pcie_port->regs->app.soc_int[i].status_1 = &regs->app.soc_int_per_func[i].status_1;
pcie_port->regs->app.soc_int[i].status_2 = &regs->app.soc_int_per_func[i].status_2;
pcie_port->regs->app.soc_int[i].status_3 = &regs->app.soc_int_per_func[i].status_3;
pcie_port->regs->app.soc_int[i].mask_inta_leg_0 = &regs->app.soc_int_per_func[i].mask_inta_leg_0;
pcie_port->regs->app.soc_int[i].mask_inta_leg_1 = &regs->app.soc_int_per_func[i].mask_inta_leg_1;
pcie_port->regs->app.soc_int[i].mask_inta_leg_2 = &regs->app.soc_int_per_func[i].mask_inta_leg_2;
pcie_port->regs->app.soc_int[i].mask_inta_leg_3 = &regs->app.soc_int_per_func[i].mask_inta_leg_3;
pcie_port->regs->app.soc_int[i].mask_msi_leg_0 = &regs->app.soc_int_per_func[i].mask_msi_leg_0;
pcie_port->regs->app.soc_int[i].mask_msi_leg_1 = &regs->app.soc_int_per_func[i].mask_msi_leg_1;
pcie_port->regs->app.soc_int[i].mask_msi_leg_2 = &regs->app.soc_int_per_func[i].mask_msi_leg_2;
pcie_port->regs->app.soc_int[i].mask_msi_leg_3 = &regs->app.soc_int_per_func[i].mask_msi_leg_3;
}
@ -1224,6 +1230,7 @@ al_pcie_port_handle_init(
pcie_port->regs->app.parity = &regs->app.parity;
pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair;
pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair;
pcie_port->regs->app.cfg_func_ext = &regs->app.cfg_func_ext;
for (i = 0; i < AL_MAX_NUM_OF_PFS; i++)
pcie_port->regs->app.status_per_func[i] = &regs->app.status_per_func[i];
@ -1260,6 +1267,10 @@ al_pcie_port_handle_init(
/* set maximum number of physical functions */
pcie_port->max_num_of_pfs = al_pcie_port_max_num_of_pfs_get(pcie_port);
/* Clear 'nof_p_hdr' & 'nof_np_hdr' to later know if they where changed by the user */
pcie_port->ib_hcrd_config.nof_np_hdr = 0;
pcie_port->ib_hcrd_config.nof_p_hdr = 0;
al_dbg("pcie port handle initialized. port id: %d, rev_id %d, regs base %p\n",
port_id, pcie_port->rev_id, pcie_reg_base);
return 0;
@ -1294,6 +1305,12 @@ al_pcie_pf_handle_init(
return 0;
}
/** Get port revision ID */
int al_pcie_port_rev_id_get(struct al_pcie_port *pcie_port)
{
return pcie_port->rev_id;
}
/************************** Pre PCIe Port Enable API **************************/
/** configure pcie operating mode (root complex or endpoint) */
@ -1346,7 +1363,7 @@ al_pcie_port_operating_mode_config(
"EndPoint" : "Root Complex");
return 0;
}
al_info("PCIe %d: set operating mode to %s\n",
al_dbg("PCIe %d: set operating mode to %s\n",
pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ?
"EndPoint" : "Root Complex");
AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK,
@ -1362,6 +1379,7 @@ int
al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes)
{
struct al_pcie_regs *regs = pcie_port->regs;
uint32_t active_lanes_val;
if (al_pcie_port_is_enabled(pcie_port)) {
al_err("PCIe %d: already enabled, cannot set max lanes\n",
@ -1370,7 +1388,7 @@ al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes)
}
/* convert to bitmask format (4 ->'b1111, 2 ->'b11, 1 -> 'b1) */
uint32_t active_lanes_val = AL_PCIE_PARSE_LANES(lanes);
active_lanes_val = AL_PCIE_PARSE_LANES(lanes);
al_reg_write32_masked(regs->axi.pcie_global.conf,
(pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
@ -1387,11 +1405,7 @@ al_pcie_port_max_num_of_pfs_set(
struct al_pcie_port *pcie_port,
uint8_t max_num_of_pfs)
{
if (al_pcie_port_is_enabled(pcie_port)) {
al_err("PCIe %d: already enabled, cannot set max num of PFs\n",
pcie_port->port_id);
return -EINVAL;
}
struct al_pcie_regs *regs = pcie_port->regs;
if (pcie_port->rev_id == AL_PCIE_REV_ID_3)
al_assert(max_num_of_pfs <= REV3_MAX_NUM_OF_PFS);
@ -1400,6 +1414,33 @@ al_pcie_port_max_num_of_pfs_set(
pcie_port->max_num_of_pfs = max_num_of_pfs;
if (al_pcie_port_is_enabled(pcie_port) && (pcie_port->rev_id == AL_PCIE_REV_ID_3)) {
enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port);
al_bool is_multi_pf =
((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1));
/* Set maximum physical function numbers */
al_reg_write32_masked(
&regs->port_regs->timer_ctrl_max_func_num,
PCIE_PORT_GEN3_MAX_FUNC_NUM,
pcie_port->max_num_of_pfs - 1);
al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
/**
* in EP mode, when we have more than 1 PF we need to assert
* multi-pf support so the host scan all PFs
*/
al_reg_write32_masked((uint32_t __iomem *)
(&regs->core_space[0].config_header[0] +
(PCIE_BIST_HEADER_TYPE_BASE >> 2)),
PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK,
is_multi_pf ? PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK : 0);
al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE);
}
return 0;
}
@ -1503,6 +1544,28 @@ al_pcie_operating_mode_get(
return AL_PCIE_OPERATING_MODE_UNKNOWN;
}
/* PCIe AXI quality of service configuration */
void al_pcie_axi_qos_config(
struct al_pcie_port *pcie_port,
unsigned int arqos,
unsigned int awqos)
{
struct al_pcie_regs *regs = pcie_port->regs;
al_assert(pcie_port);
al_assert(arqos <= PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_VAL_MAX);
al_assert(awqos <= PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_VAL_MAX);
al_reg_write32_masked(
regs->axi.ctrl.master_arctl,
PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK,
arqos << PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT);
al_reg_write32_masked(
regs->axi.ctrl.master_awctl,
PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK,
awqos << PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT);
}
/**************************** PCIe Port Enable API ****************************/
/** Enable PCIe port (deassert reset) */
@ -1518,17 +1581,19 @@ al_pcie_port_enable(struct al_pcie_port *pcie_port)
/**
* Set inbound header credit and outstanding outbound reads defaults
* if the port initiator doesn't set it.
* Must be called before port enable (PCIE_EXIST)
*/
al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port);
if ((pcie_port->ib_hcrd_config.nof_np_hdr == 0) ||
(pcie_port->ib_hcrd_config.nof_p_hdr == 0))
al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port);
/*
* Disable ATS capability
* - must be done before core reset deasserted
* - rev_id 0 - no effect, but no harm
*/
if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_1) ||
if ((pcie_port->rev_id == AL_PCIE_REV_ID_1) ||
(pcie_port->rev_id == AL_PCIE_REV_ID_2)) {
al_reg_write32_masked(
regs->axi.ordering.pos_cntl,
@ -1679,26 +1744,8 @@ al_pcie_port_config(struct al_pcie_port *pcie_port,
}
if (pcie_port->rev_id == AL_PCIE_REV_ID_3) {
/* Set maximum physical function numbers */
al_reg_write32_masked(
&regs->port_regs->timer_ctrl_max_func_num,
PCIE_PORT_GEN3_MAX_FUNC_NUM,
pcie_port->max_num_of_pfs - 1);
al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE);
/**
* in EP mode, when we have more than 1 PF we need to assert
* multi-pf support so the host scan all PFs
*/
if ((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1)) {
al_reg_write32_masked((uint32_t __iomem *)
(&regs->core_space[0].config_header[0] +
(PCIE_BIST_HEADER_TYPE_BASE >> 2)),
PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK,
PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK);
}
/* Disable TPH next pointer */
for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) {
al_reg_write32_masked(regs->core_space[i].tph_cap_base,
@ -1713,6 +1760,8 @@ al_pcie_port_config(struct al_pcie_port *pcie_port,
if (status)
goto done;
al_pcie_port_max_num_of_pfs_set(pcie_port, pcie_port->max_num_of_pfs);
al_pcie_port_ram_parity_int_config(pcie_port, params->enable_ram_parity_int);
al_pcie_port_axi_parity_int_config(pcie_port, params->enable_axi_parity_int);
@ -1734,14 +1783,6 @@ al_pcie_port_config(struct al_pcie_port *pcie_port,
if (status)
goto done;
if (params->tl_credits)
status = al_pcie_port_tl_credits_config(pcie_port, params->tl_credits);
if (status)
goto done;
if (params->features)
al_pcie_port_features_config(pcie_port, params->features);
if (params->sris_params)
status = al_pcie_port_sris_config(pcie_port, params->sris_params,
params->link_params->max_speed);
@ -1904,6 +1945,19 @@ al_pcie_link_stop(struct al_pcie_port *pcie_port)
return 0;
}
/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */
al_bool al_pcie_is_link_started(struct al_pcie_port *pcie_port)
{
struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs;
uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init);
uint8_t ltssm_en = AL_REG_FIELD_GET(port_init,
PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK,
PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT);
return ltssm_en;
}
/* wait for link up indication */
int
al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms)
@ -1912,7 +1966,7 @@ al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms)
while (wait_count-- > 0) {
if (al_pcie_check_link(pcie_port, NULL)) {
al_info("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id);
al_dbg("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id);
return 0;
} else
al_dbg("PCIe_%d: No link up, %d attempts remaining\n",
@ -1920,7 +1974,7 @@ al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms)
al_udelay(AL_PCIE_LINKUP_WAIT_INTERVAL);
}
al_info("PCIE_%d: link is not established in time\n",
al_dbg("PCIE_%d: link is not established in time\n",
pcie_port->port_id);
return ETIMEDOUT;
@ -1936,6 +1990,15 @@ al_pcie_link_status(struct al_pcie_port *pcie_port,
al_assert(status);
if (!al_pcie_port_is_enabled(pcie_port)) {
al_dbg("PCIe %d: port not enabled, no link.\n", pcie_port->port_id);
status->link_up = AL_FALSE;
status->speed = AL_PCIE_LINK_SPEED_DEFAULT;
status->lanes = 0;
status->ltssm_state = 0;
return 0;
}
status->link_up = al_pcie_check_link(pcie_port, &status->ltssm_state);
if (!status->link_up) {
@ -1962,7 +2025,7 @@ al_pcie_link_status(struct al_pcie_port *pcie_port,
pcie_port->port_id, pcie_lnksta);
}
status->lanes = (pcie_lnksta & AL_PCI_EXP_LNKSTA_NLW) >> AL_PCI_EXP_LNKSTA_NLW_SHIFT;
al_info("PCIe %d: Link up. speed gen%d negotiated width %d\n",
al_dbg("PCIe %d: Link up. speed gen%d negotiated width %d\n",
pcie_port->port_id, status->speed, status->lanes);
return 0;
@ -2143,7 +2206,7 @@ al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, al_bool enable_axi_sno
struct al_pcie_regs *regs = pcie_port->regs;
/* Set snoop mode */
al_info("PCIE_%d: snoop mode %s\n",
al_dbg("PCIE_%d: snoop mode %s\n",
pcie_port->port_id, enable_axi_snoop ? "enable" : "disable");
if (enable_axi_snoop) {
@ -2311,6 +2374,19 @@ al_pcie_app_req_retry_set(
mask, (en == AL_TRUE) ? mask : 0);
}
/* Check if deferring incoming configuration requests is enabled or not */
al_bool al_pcie_app_req_retry_get_status(struct al_pcie_port *pcie_port)
{
struct al_pcie_regs *regs = pcie_port->regs;
uint32_t pm_control;
uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ?
PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN :
PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN;
pm_control = al_reg_read32(regs->app.global_ctrl.pm_control);
return (pm_control & mask) ? AL_TRUE : AL_FALSE;
}
/*************** Internal Address Translation Unit (ATU) API ******************/
/** program internal ATU region entry */
@ -2345,6 +2421,7 @@ al_pcie_atu_region_set(
if (!atu_region->enforce_ob_atu_region_set) {
al_err("PCIe %d: setting OB iATU after link is started is not allowed\n",
pcie_port->port_id);
al_assert(AL_FALSE);
return -EINVAL;
} else {
al_info("PCIe %d: setting OB iATU even after link is started\n",
@ -2369,7 +2446,63 @@ al_pcie_atu_region_set(
/* configure the limit, not needed when working in BAR match mode */
if (atu_region->match_mode == 0) {
uint32_t limit_reg_val;
if (pcie_port->rev_id > AL_PCIE_REV_ID_0) {
uint32_t *limit_ext_reg =
(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ?
&regs->app.atu.out_mask_pair[atu_region->index / 2] :
&regs->app.atu.in_mask_pair[atu_region->index / 2];
uint32_t limit_ext_reg_mask =
(atu_region->index % 2) ?
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK :
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK;
unsigned int limit_ext_reg_shift =
(atu_region->index % 2) ?
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT :
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT;
uint64_t limit_sz_msk =
atu_region->limit - atu_region->base_addr;
uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >>
32) & 0xFFFFFFFF);
if (limit_ext_reg_val) {
limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF);
al_assert(limit_reg_val == 0xFFFFFFFF);
} else {
limit_reg_val = (uint32_t)(atu_region->limit &
0xFFFFFFFF);
}
al_reg_write32_masked(
limit_ext_reg,
limit_ext_reg_mask,
limit_ext_reg_val << limit_ext_reg_shift);
al_reg_write32(&regs->port_regs->iatu.limit_addr,
limit_reg_val);
}
/**
* Addressing RMN: 3186
*
* RMN description:
* Bug in SNPS IP (versions 4.21 , 4.10a-ea02)
* In CFG request created via outbound atu (shift mode) bits [27:12] go to
* [31:16] , the shifting is correct , however the ATU leaves bit [15:12]
* to their original values, this is then transmited in the tlp .
* Those bits are currently reserved ,bit might be non-resv. in future generations .
*
* Software flow:
* Enable HW fix
* rev=REV1,REV2 set bit 15 in corresponding app_reg.atu.out_mask
* rev>REV2 set corresponding bit is app_reg.atu.reg_out_mask
*/
if ((atu_region->cfg_shift_mode == AL_TRUE) &&
(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND)) {
if (pcie_port->rev_id > AL_PCIE_REV_ID_2) {
al_reg_write32_masked(regs->app.atu.reg_out_mask,
1 << (atu_region->index) ,
1 << (atu_region->index));
} else {
uint32_t *limit_ext_reg =
(atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ?
&regs->app.atu.out_mask_pair[atu_region->index / 2] :
@ -2382,29 +2515,12 @@ al_pcie_atu_region_set(
(atu_region->index % 2) ?
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT :
PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT;
uint64_t limit_sz_msk =
atu_region->limit - atu_region->base_addr;
uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >>
32) & 0xFFFFFFFF);
if (limit_ext_reg_val) {
limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF);
al_assert(limit_reg_val == 0xFFFFFFFF);
} else {
limit_reg_val = (uint32_t)(atu_region->limit &
0xFFFFFFFF);
}
al_reg_write32_masked(
limit_ext_reg,
limit_ext_reg_mask,
limit_ext_reg_val << limit_ext_reg_shift);
} else {
limit_reg_val = (uint32_t)(atu_region->limit & 0xFFFFFFFF);
limit_ext_reg,
limit_ext_reg_mask,
(AL_BIT(15)) << limit_ext_reg_shift);
}
al_reg_write32(&regs->port_regs->iatu.limit_addr,
limit_reg_val);
}
reg = 0;
@ -2505,7 +2621,22 @@ al_pcie_axi_io_config(
PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN);
}
/************** Interrupt generation (Endpoint mode Only) API *****************/
/************** Interrupt and Event generation (Endpoint mode Only) API *****************/
int al_pcie_pf_flr_done_gen(struct al_pcie_pf *pcie_pf)
{
struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
unsigned int pf_num = pcie_pf->pf_num;
al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num],
PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE,
PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE);
al_udelay(AL_PCIE_FLR_DONE_INTERVAL);
al_reg_write32_masked(regs->app.global_ctrl.events_gen[pf_num],
PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE, 0);
return 0;
}
/** generate INTx Assert/DeAssert Message */
int
@ -2607,15 +2738,16 @@ al_pcie_msix_masked(struct al_pcie_pf *pcie_pf)
}
/******************** Advanced Error Reporting (AER) API **********************/
/** configure AER capability */
int
al_pcie_aer_config(
struct al_pcie_pf *pcie_pf,
struct al_pcie_aer_params *params)
/************************* Auxiliary functions ********************************/
/* configure AER capability */
static int
al_pcie_aer_config_aux(
struct al_pcie_port *pcie_port,
unsigned int pf_num,
struct al_pcie_aer_params *params)
{
struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer;
struct al_pcie_regs *regs = pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
uint32_t reg_val;
reg_val = al_reg_read32(&aer_regs->header);
@ -2641,8 +2773,22 @@ al_pcie_aer_config(
(params->ecrc_gen_en ? PCIE_AER_CTRL_STAT_ECRC_GEN_EN : 0) |
(params->ecrc_chk_en ? PCIE_AER_CTRL_STAT_ECRC_CHK_EN : 0));
/**
* Addressing RMN: 5119
*
* RMN description:
* ECRC generation for outbound request translated by iATU is effected
* by iATU setting instead of ecrc_gen_bit in AER
*
* Software flow:
* When enabling ECRC generation, set the outbound iATU to generate ECRC
*/
if (params->ecrc_gen_en == AL_TRUE) {
al_pcie_ecrc_gen_ob_atu_enable(pcie_port, pf_num);
}
al_reg_write32_masked(
regs->core_space[pcie_pf->pf_num].pcie_dev_ctrl_status,
regs->core_space[pf_num].pcie_dev_ctrl_status,
PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN |
PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN |
PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN |
@ -2663,12 +2809,14 @@ al_pcie_aer_config(
return 0;
}
/** AER uncorretable errors get and clear */
unsigned int
al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf)
/** AER uncorrectable errors get and clear */
static unsigned int
al_pcie_aer_uncorr_get_and_clear_aux(
struct al_pcie_port *pcie_port,
unsigned int pf_num)
{
struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer;
struct al_pcie_regs *regs = pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
uint32_t reg_val;
reg_val = al_reg_read32(&aer_regs->uncorr_err_stat);
@ -2677,12 +2825,14 @@ al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf)
return reg_val;
}
/** AER corretable errors get and clear */
unsigned int
al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf)
/** AER correctable errors get and clear */
static unsigned int
al_pcie_aer_corr_get_and_clear_aux(
struct al_pcie_port *pcie_port,
unsigned int pf_num)
{
struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer;
struct al_pcie_regs *regs = pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
uint32_t reg_val;
reg_val = al_reg_read32(&aer_regs->corr_err_stat);
@ -2696,19 +2846,123 @@ al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf)
#endif
/** AER get the header for the TLP corresponding to a detected error */
void
al_pcie_aer_err_tlp_hdr_get(
struct al_pcie_pf *pcie_pf,
static void
al_pcie_aer_err_tlp_hdr_get_aux(
struct al_pcie_port *pcie_port,
unsigned int pf_num,
uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
{
struct al_pcie_regs *regs = pcie_pf->pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer;
struct al_pcie_regs *regs = pcie_port->regs;
struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pf_num].aer;
int i;
for (i = 0; i < AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS; i++)
hdr[i] = al_reg_read32(&aer_regs->header_log[i]);
}
/******************** EP AER functions **********************/
/** configure EP physical function AER capability */
int al_pcie_aer_config(
struct al_pcie_pf *pcie_pf,
struct al_pcie_aer_params *params)
{
al_assert(pcie_pf);
al_assert(params);
return al_pcie_aer_config_aux(
pcie_pf->pcie_port, pcie_pf->pf_num, params);
}
/** EP physical function AER uncorrectable errors get and clear */
unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf)
{
al_assert(pcie_pf);
return al_pcie_aer_uncorr_get_and_clear_aux(
pcie_pf->pcie_port, pcie_pf->pf_num);
}
/** EP physical function AER correctable errors get and clear */
unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf)
{
al_assert(pcie_pf);
return al_pcie_aer_corr_get_and_clear_aux(
pcie_pf->pcie_port, pcie_pf->pf_num);
}
/**
* EP physical function AER get the header for
* the TLP corresponding to a detected error
* */
void al_pcie_aer_err_tlp_hdr_get(
struct al_pcie_pf *pcie_pf,
uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
{
al_assert(pcie_pf);
al_assert(hdr);
al_pcie_aer_err_tlp_hdr_get_aux(
pcie_pf->pcie_port, pcie_pf->pf_num, hdr);
}
/******************** RC AER functions **********************/
/** configure RC port AER capability */
int al_pcie_port_aer_config(
struct al_pcie_port *pcie_port,
struct al_pcie_aer_params *params)
{
al_assert(pcie_port);
al_assert(params);
/**
* For RC mode there's no PFs (neither PF handles),
* therefore PF#0 is used
* */
return al_pcie_aer_config_aux(pcie_port, 0, params);
}
/** RC port AER uncorrectable errors get and clear */
unsigned int al_pcie_port_aer_uncorr_get_and_clear(
struct al_pcie_port *pcie_port)
{
al_assert(pcie_port);
/**
* For RC mode there's no PFs (neither PF handles),
* therefore PF#0 is used
* */
return al_pcie_aer_uncorr_get_and_clear_aux(pcie_port, 0);
}
/** RC port AER correctable errors get and clear */
unsigned int al_pcie_port_aer_corr_get_and_clear(
struct al_pcie_port *pcie_port)
{
al_assert(pcie_port);
/**
* For RC mode there's no PFs (neither PF handles),
* therefore PF#0 is used
* */
return al_pcie_aer_corr_get_and_clear_aux(pcie_port, 0);
}
/** RC port AER get the header for the TLP corresponding to a detected error */
void al_pcie_port_aer_err_tlp_hdr_get(
struct al_pcie_port *pcie_port,
uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS])
{
al_assert(pcie_port);
al_assert(hdr);
/**
* For RC mode there's no PFs (neither PF handles),
* therefore PF#0 is used
* */
al_pcie_aer_err_tlp_hdr_get_aux(pcie_port, 0, hdr);
}
/********************** Loopback mode (RC and Endpoint modes) ************/
/** enter local pipe loopback mode */

View File

@ -85,7 +85,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* - Root Complex mode
* - Set the Max Link Speed to Gen2
* - Set the max lanes width to 2 (x2)
* - Disable reversal mode
* - Enable Snoops to support I/O Hardware cache coherency
* - Enable pcie core RAM parity
* - Enable pcie core AXI parity
@ -97,7 +96,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @code
* - struct al_pcie_link_params link_params = {
* AL_PCIE_LINK_SPEED_GEN2,
* AL_FALSE, // disable reversal mode
* AL_PCIE_MPS_DEFAULT};
*
* - struct al_pcie_port_config_params config_params = {
@ -162,14 +160,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/********************************* Constants **********************************/
/******************************************************************************/
/** Inbound header credits sum - rev 0/1/2 */
#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97
/** Inbound header credits sum - rev 3 */
#define AL_PCIE_REV3_IB_HCRD_SUM 259
/**
* PCIe Core revision IDs:
* ID_1: Alpine V1
* ID_2: Alpine V2 x4
* ID_3: Alpine V2 x8
*/
#define AL_PCIE_REV_ID_1 1
#define AL_PCIE_REV_ID_2 2
#define AL_PCIE_REV_ID_3 3
/** Number of extended registers */
#define AL_PCIE_EX_REGS_NUM 40
/*******************************************************************************
* The inbound flow control for headers is programmable per P, NP and CPL
* transactions types. The following parameters define the total number of
* available header flow controls for all types.
******************************************************************************/
/** Inbound header credits sum - rev1/2 */
#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97
/** Inbound header credits sum - rev3 */
#define AL_PCIE_REV3_IB_HCRD_SUM 259
/*******************************************************************************
* PCIe AER uncorrectable error bits
* To be used with the following functions:
@ -232,9 +245,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/**
* al_pcie_ib_hcrd_config: data structure internally used in order to config
* inbound posted/non-posted parameters.
* Note: it's required to have this structure in pcie_port handle since it has
* a state (required/not-required) which is determined by outbound
* outstanding configuration
* Note: this is a private member in pcie_port handle and MUST NOT be modified
* by the user.
*/
struct al_pcie_ib_hcrd_config {
/* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */
@ -251,10 +263,6 @@ enum al_pcie_max_payload_size {
AL_PCIE_MPS_DEFAULT,
AL_PCIE_MPS_128 = 0,
AL_PCIE_MPS_256 = 1,
AL_PCIE_MPS_512 = 2,
AL_PCIE_MPS_1024 = 3,
AL_PCIE_MPS_2048 = 4,
AL_PCIE_MPS_4096 = 5,
};
/**
@ -271,10 +279,12 @@ struct al_pcie_port {
void *ex_regs;
void __iomem *pbs_regs;
/* Revision ID */
/* Rev ID */
uint8_t rev_id;
unsigned int port_id;
uint8_t max_lanes;
/* For EP mode only */
uint8_t max_num_of_pfs;
/* Internally used */
@ -284,6 +294,8 @@ struct al_pcie_port {
/**
* al_pcie_pf: the pf handle, a data structure used to handle PF specific
* functionality. Initialized using "al_pcie_pf_handle_init()"
*
* Note: This structure should be used for EP mode only
*/
struct al_pcie_pf {
unsigned int pf_num;
@ -318,15 +330,13 @@ struct al_pcie_max_capability {
al_bool root_complex_mode_supported;
enum al_pcie_link_speed max_speed;
uint8_t max_lanes;
al_bool reversal_supported;
uint8_t atu_regions_num;
uint32_t atu_min_size;
uint32_t atu_min_size; /* Size granularity: 4 Kbytes */
};
/** PCIe link related parameters */
struct al_pcie_link_params {
enum al_pcie_link_speed max_speed;
al_bool enable_reversal;
enum al_pcie_link_speed max_speed;
enum al_pcie_max_payload_size max_payload_size;
};
@ -362,22 +372,22 @@ struct al_pcie_gen3_params {
uint8_t local_fs; /* Low Frequency (LF) Value for Gen3 Transmit Equalization */
};
/** Transport Layer credits parameters */
struct al_pcie_tl_credits_params {
};
/** Various configuration features */
struct al_pcie_features {
/**
* Enable MSI fix from the SATA to the PCIe EP
* Only valid for port 0, when enabled as EP
*/
al_bool sata_ep_msi_fix;
};
/**
* Inbound posted/non-posted header credits and outstanding outbound reads
* completion header configuration
* completion header configuration.
*
* This structure controls the resource partitioning of an important resource in
* the PCIe port. This resource includes the PCIe TLP headers coming on the PCIe
* port, and is shared between three types:
* - Inbound Non-posted, which are PCIe Reads as well as PCIe Config Cycles
* - Inbound Posted, i.e. PCIe Writes
* - Inbound Read-completion, which are the completions matching and outbound
* reads issued previously by the same core.
* The programmer need to take into consideration that a given outbound read
* request could be split on the return path into Ceiling[MPS_Size / 64] + 1
* of Read Completions.
* Programmers are not expected to modify these setting except for rare cases,
* where a different ratio between Posted-Writes and Read-Completions is desired
*
* Constraints:
* - nof_cpl_hdr + nof_np_hdr + nof_p_hdr ==
@ -411,13 +421,26 @@ struct al_pcie_ib_hcrd_os_ob_reads_config {
unsigned int nof_p_hdr;
};
/** PCIe Ack/Nak Latency and Replay timers */
/**
* PCIe Ack/Nak Latency and Replay timers
*
* Note: Programmer is not expected to modify these values unless working in
* very slow external devices like low-end FPGA or hardware devices
* emulated in software
*/
struct al_pcie_latency_replay_timers {
uint16_t round_trip_lat_limit;
uint16_t replay_timer_limit;
};
/* SRIS KP counter values */
/**
* SRIS KP counter values
*
* Description: SRIS is PCI SIG ECN, that enables the two peers on a given PCIe
* link to run with Separate Reference clock with Independent Spread spectrum
* clock and requires inserting PCIe SKP symbols on the link in faster frequency
* that original PCIe spec
*/
struct al_pcie_sris_params {
/** set to AL_TRUE to use defaults and ignore the other parameters */
al_bool use_defaults;
@ -425,7 +448,23 @@ struct al_pcie_sris_params {
uint16_t kp_counter_gen21;
};
/** Relaxed ordering params */
/**
* Relaxed ordering params
* Enable ordering relaxations for applications that does not require
* enforcement of 'completion must not bypass posted' ordering rule.
*
* Recommendation:
* - For downstream port, set enable_tx_relaxed_ordering
* - For upstream port
* - set enable_rx_relaxed_ordering
* - set enable tx_relaxed_ordering for emulated EP.
*
* Defaults:
* - For Root-Complex:
* - tx_relaxed_ordering = AL_FALSE, rx_relaxed_ordering = AL_TRUE
* - For End-Point:
* - tx_relaxed_ordering = AL_TRUE, rx_relaxed_ordering = AL_FALSE
*/
struct al_pcie_relaxed_ordering_params {
al_bool enable_tx_relaxed_ordering;
al_bool enable_rx_relaxed_ordering;
@ -445,20 +484,26 @@ struct al_pcie_port_config_params {
struct al_pcie_latency_replay_timers *lat_rply_timers;
struct al_pcie_gen2_params *gen2_params;
struct al_pcie_gen3_params *gen3_params;
struct al_pcie_tl_credits_params *tl_credits;
struct al_pcie_features *features;
/* Sets all internal timers to Fast Mode for speeding up simulation.*/
/*
* Sets all internal timers to Fast Mode for speeding up simulation.
* this varible should be set always to AL_FALSE unless user is running
* on simulation setup
*/
al_bool fast_link_mode;
/*
* when true, the PCI unit will return Slave Error/Decoding Error to the master unit in case
* of error. when false, the value 0xFFFFFFFF will be returned without error indication.
* when true, the PCI unit will return Slave Error/Decoding Error to any
* I/O Fabric master or Internal Processors in case of error.
* when false, the value 0xFFFFFFFF will be returned without error indication.
*/
al_bool enable_axi_slave_err_resp;
struct al_pcie_sris_params *sris_params;
struct al_pcie_relaxed_ordering_params *relaxed_ordering_params;
};
/** BAR register configuration parameters (Endpoint Mode only) */
/**
* BAR register configuration parameters
* Note: This structure should be used for EP mode only
*/
struct al_pcie_ep_bar_params {
al_bool enable;
al_bool memory_space; /**< memory or io */
@ -467,12 +512,30 @@ struct al_pcie_ep_bar_params {
uint64_t size; /* the bar size in bytes */
};
/** PF config params (EP mode only) */
/**
* PF config params (EP mode only)
* Note: This structure should be used for EP mode only
*/
struct al_pcie_pf_config_params {
/**
* disable advertising D1 and D3hot state
* Recommended to be AL_TRUE
*/
al_bool cap_d1_d3hot_dis;
/**
* disable advertising support for Function-Level-Reset
* Recommended to be AL_FALSE
*/
al_bool cap_flr_dis;
/*
* disable advertising Advanced power management states
*/
al_bool cap_aspm_dis;
al_bool bar_params_valid;
/*
* Note: only bar_params[0], [2] and [4] can have memory_64_bit enabled
* and in such case, the next bar ([1], [3], or [5] respectively) is not used
*/
struct al_pcie_ep_bar_params bar_params[6];
struct al_pcie_ep_bar_params exp_bar_params;/* expansion ROM BAR*/
};
@ -481,7 +544,7 @@ struct al_pcie_pf_config_params {
struct al_pcie_link_status {
al_bool link_up;
enum al_pcie_link_speed speed;
uint8_t lanes;
uint8_t lanes; /* Number of lanes */
uint8_t ltssm_state;
};
@ -491,18 +554,26 @@ struct al_pcie_lane_status {
enum al_pcie_link_speed requested_speed;
};
/** PCIe MSIX capability configuration parameters */
/**
* PCIe MSIX capability configuration parameters
* Note: This structure should be used for EP mode only
*/
struct al_pcie_msix_params {
/* Number of entries - size can be up to: 2024 */
uint16_t table_size;
uint16_t table_offset;
uint8_t table_bar;
uint16_t pba_offset;
/* which bar to use when calculating the PBA table address and adding offset to */
uint16_t pba_bar;
};
/** PCIE AER capability parameters */
struct al_pcie_aer_params {
/** ECRC Generation Enable */
/** ECRC Generation Enable
* while this feature is powerful, all known Chip-sets and processors
* do not support it as of 2015
*/
al_bool ecrc_gen_en;
/** ECRC Check Enable */
al_bool ecrc_chk_en;
@ -562,6 +633,13 @@ int al_pcie_pf_handle_init(
struct al_pcie_port *pcie_port,
unsigned int pf_num);
/**
* Get port revision ID
* @param pcie_port pcie port handle
* @return Port rev_id
*/
int al_pcie_port_rev_id_get(struct al_pcie_port *pcie_port);
/************************** Pre PCIe Port Enable API **************************/
/**
@ -582,7 +660,8 @@ int al_pcie_port_operating_mode_config(struct al_pcie_port *pcie_port,
* This function can be called only before enabling the controller using al_pcie_port_enable().
*
* @param pcie_port pcie port handle
* @param lanes number of lanes
* @param lanes number of lanes (must be 1,2,4,8,16 and not any other value)
*
* Note: this function must be called before any al_pcie_port_config() calls
*
* @return 0 if no error found.
@ -593,7 +672,12 @@ int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes);
* Set maximum physical function numbers
* @param pcie_port pcie port handle
* @param max_num_of_pfs number of physical functions
* Note: this function must be called before any al_pcie_pf_config() calls
*
* Notes:
* - this function must be called before any al_pcie_pf_config() calls
* - exposed on a given PCIe Endpoint port
* - PCIe rev1/rev2 supports only single Endpoint
* - PCIe rev3 can support up to 4
*/
int al_pcie_port_max_num_of_pfs_set(
struct al_pcie_port *pcie_port,
@ -619,9 +703,27 @@ int al_pcie_port_ib_hcrd_os_ob_reads_config(
enum al_pcie_operating_mode al_pcie_operating_mode_get(
struct al_pcie_port *pcie_port);
/**
* PCIe AXI quality of service configuration
*
* @param pcie_port
* Initialized PCIe port handle
* @param arqos
* AXI read quality of service (0 - 15)
* @param awqos
* AXI write quality of service (0 - 15)
*/
void al_pcie_axi_qos_config(
struct al_pcie_port *pcie_port,
unsigned int arqos,
unsigned int awqos);
/**************************** PCIe Port Enable API ****************************/
/** Enable PCIe unit (deassert reset)
/**
* Enable PCIe unit (deassert reset)
* This function only enables the port, without any configuration/link
* functionality. Should be called before starting any configuration/link API
*
* @param pcie_port pcie port handle
*
@ -637,6 +739,8 @@ void al_pcie_port_disable(struct al_pcie_port *pcie_port);
/**
* Port memory shutdown/up
* Memory shutdown should be called for an unused ports for power-saving
*
* Caution: This function can be called only when the controller is disabled
*
* @param pcie_port pcie port handle
@ -669,7 +773,7 @@ int al_pcie_port_config(struct al_pcie_port *pcie_port,
const struct al_pcie_port_config_params *params);
/**
* @brief Configure a specific PF (EP params, sriov params, ...)
* @brief Configure a specific PF
* this function must be called before any datapath transactions
*
* @param pcie_pf pcie pf handle
@ -685,7 +789,8 @@ int al_pcie_pf_config(
/**
* @brief start pcie link
*
* This function starts the link and should be called only after port is enabled
* and pre port-enable and configurations are done
* @param pcie_port pcie port handle
*
* @return 0 if no error found
@ -701,6 +806,14 @@ int al_pcie_link_start(struct al_pcie_port *pcie_port);
*/
int al_pcie_link_stop(struct al_pcie_port *pcie_port);
/**
* @brief check if pcie link is started
* Note that this function checks if link is started rather than link is up
* @param pcie_port pcie port handle
* @return AL_TRUE if link is started and AL_FALSE otherwise
*/
al_bool al_pcie_is_link_started(struct al_pcie_port *pcie_port);
/**
* @brief trigger link-disable
*
@ -753,6 +866,10 @@ void al_pcie_lane_status_get(
/**
* @brief trigger hot reset
* this function initiates In-Band reset while link is up.
* to initiate hot reset: call this function with AL_TRUE
* to exit from hos reset: call this function with AL_FALSE
* Note: This function should be called in RC mode only
*
* @param pcie_port pcie port handle
* @param enable AL_TRUE to enable hot-reset and AL_FALSE to disable it
@ -766,6 +883,7 @@ int al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable);
* this function initiates Link retraining by directing the Physical Layer LTSSM
* to the Recovery state. If the LTSSM is already in Recovery or Configuration,
* re-entering Recovery is permitted but not required.
* Note: This function should be called in RC mode only
* @param pcie_port pcie port handle
*
@ -793,7 +911,9 @@ int al_pcie_link_change_width(struct al_pcie_port *pcie_port, uint8_t width);
/************************** Snoop Configuration API ***************************/
/**
* @brief configure pcie port axi snoop
* @brief configure pcie port axi snoop
* This enable the inbound PCIe posted write data or the Read completion data to
* snoop the internal processor caches for I/O cache coherency
*
* @param pcie_port pcie port handle
* @param enable_axi_snoop enable snoop.
@ -807,7 +927,10 @@ int al_pcie_port_snoop_config(struct al_pcie_port *pcie_port,
/************************** Configuration Space API ***************************/
/**
* Configuration Space Access Through PCI-E_ECAM_Ext PASW (RC mode only)
* Configuration Space Access Through PCI-E_ECAM_Ext PASW
* This feature enables the internal processors to generate configuration cycles
* on the PCIe ports by writing to part of the processor memory space marked by
* the PCI-E_EXCAM_Ext address window
*/
/**
@ -852,6 +975,11 @@ void al_pcie_local_cfg_space_write(
/**
* @brief set target_bus and mask_target_bus
*
* Call this function with target_bus set to the required bus of the next
* outbound config access to be issued. No need to call that function if the
* next config access bus equals to the last one.
*
* @param pcie_port pcie port handle
* @param target_bus
* @param mask_target_bus
@ -875,6 +1003,8 @@ int al_pcie_target_bus_get(struct al_pcie_port *pcie_port,
/**
* Set secondary bus number
*
* Same as al_pcie_target_bus_set but with secondary bus
*
* @param pcie_port pcie port handle
* @param secbus pci secondary bus number
*
@ -885,6 +1015,8 @@ int al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus);
/**
* Set subordinary bus number
*
* Same as al_pcie_target_bus_set but with subordinary bus
*
* @param pcie_port pcie port handle
* @param subbus the highest bus number of all of the buses that can be reached
* downstream of the PCIE instance.
@ -897,13 +1029,22 @@ int al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port,uint8_t subbus);
* @brief Enable/disable deferring incoming configuration requests until
* initialization is complete. When enabled, the core completes incoming
* configuration requests with a Configuration Request Retry Status.
* Other incoming Requests complete with Unsupported Request status.
* Other incoming non-configuration Requests complete with Unsupported Request status.
*
* Note: This function should be used for EP mode only
*
* @param pcie_port pcie port handle
* @param en enable/disable
*/
void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en);
/**
* @brief Check if deferring incoming configuration requests is enabled or not
* @param pcie_port pcie port handle
* @return AL_TRUE is it's enabled and AL_FALSE otherwise
*/
al_bool al_pcie_app_req_retry_get_status(struct al_pcie_port *pcie_port);
/*************** Internal Address Translation Unit (ATU) API ******************/
enum al_pcie_atu_dir {
@ -911,6 +1052,7 @@ enum al_pcie_atu_dir {
AL_PCIE_ATU_DIR_INBOUND = 1,
};
/** decoding of the PCIe TLP Type as appears on the wire */
enum al_pcie_atu_tlp {
AL_PCIE_TLP_TYPE_MEM = 0,
AL_PCIE_TLP_TYPE_IO = 2,
@ -920,57 +1062,134 @@ enum al_pcie_atu_tlp {
AL_PCIE_TLP_TYPE_RESERVED = 0x1f
};
/** default response types */
enum al_pcie_atu_response {
AL_PCIE_RESPONSE_NORMAL = 0,
AL_PCIE_RESPONSE_UR = 1,
AL_PCIE_RESPONSE_CA = 2
AL_PCIE_RESPONSE_UR = 1, /* UR == Unsupported Request */
AL_PCIE_RESPONSE_CA = 2 /* CA == Completion Abort */
};
struct al_pcie_atu_region {
/**********************************************************************
* General Parameters *
**********************************************************************/
al_bool enable;
/* outbound or inbound */
enum al_pcie_atu_dir direction;
/* region index */
uint8_t index;
/* the 64-bit address that get matched with the 64-bit address incoming
* on the PCIe TLP
*/
uint64_t base_addr;
/** limit marks the region's end address. only bits [39:0] are valid
* given the Alpine PoC maximum physical address space
/**
* limit marks the region's end address.
* For Alpine V1 (PCIe rev1): only bits [39:0] are valid
* For Alpine V2 (PCIe rev2/rev3): only bits [47:0] are valid
* an access is a hit in iATU if the:
* - address >= base_addr
* - address <= base_addr + limit
*/
uint64_t limit;
/** the address that matches will be translated to this address + offset
/**
* the address that matches (hit) will be translated to:
* target_addr + offset
*
* Exmaple: accessing (base_addr + 0x1000) will be translated to:
* (target_addr + 0x1000) in case limit >= 0x1000
*/
uint64_t target_addr;
/**
* When the Invert feature is activated, an address match occurs when
* the untranslated address is not in the region bounded by the Base
* address and Limit address. Match occurs when the untranslated address
* is not in the region bounded by the base address and limit address
*/
al_bool invert_matching;
/* pcie tlp type*/
/**
* PCIe TLP type
* Can be: Mem, IO, CGF0, CFG1 or MSG
*/
enum al_pcie_atu_tlp tlp_type;
/* pcie frame header attr field*/
/**
* PCIe frame header attr field.
* When the address of a TLP is matched to this region, then the ATTR
* field of the TLP is changed to the value in this register.
*/
uint8_t attr;
/**********************************************************************
* Outbound specific Parameters *
**********************************************************************/
/**
* outbound specific params
* PCIe Message code
* MSG TLPs (Message Code). When the address of an outbound TLP is
* matched to this region, and the translated TLP TYPE field is Msg
* then the message field of the TLP is changed to the value in this
* register.
*/
/* pcie message code */
uint8_t msg_code;
al_bool cfg_shift_mode;
/**
* inbound specific params
* CFG Shift Mode. This is useful for CFG transactions where the PCIe
* configuration mechanism maps bits [27:12] of the address to the
* bus/device and function number. This allows a CFG configuration space
* to be located in any 256MB window of your application memory space
* using a 28-bit effective address.Shifts bits [27:12] of the
* untranslated address to form bits [31:16] of the translated address.
*/
al_bool cfg_shift_mode;
/**********************************************************************
* Inbound specific Parameters *
**********************************************************************/
uint8_t bar_number;
/* BAR match mode, used in EP for MEM and IO tlps*/
/**
* Match Mode. Determines Inbound matching mode for TLPs. The mode
* depends on the type of TLP that is received as follows:
* MEM-I/O: 0 = Address Match Mode
* 1 = BAR Match Mode
* CFG0 : 0 = Routing ID Match Mode
* 1 = Accept Mode
* MSG : 0 = Address Match Mode
* 1 = Vendor ID Match Mode
*/
uint8_t match_mode;
/**
* For outbound: enables taking the function number of the translated
* TLP from the PCIe core. For inbound: enables ATU function match mode
* For outbound:
* - AL_TRUE : enables taking the function number of the translated TLP
* from the PCIe core
* - AL_FALSE: no function number is taken from PCIe core
* For inbound:
* - AL_TRUE : enables ATU function match mode
* - AL_FALSE: no function match mode applied to transactions
*
* Note: this boolean is ignored in RC mode
*/
al_bool function_match_bypass_mode;
/**
* The function number to match/bypass (see previous parameter)
* Note: this parameter is ignored when previous param is FALSE
* Note: this parameter is ignored when previous parameter is AL_FALSE
*/
uint8_t function_match_bypass_mode_number;
/* response code */
/**
* setting up what is the default response for an inbound transaction
* that matches the iATU
*/
enum al_pcie_atu_response response;
/**
* Attr Match Enable. Ensures that a successful AT TLP field comparison
* match (see attr above) occurs for address translation to proceed
*/
al_bool enable_attr_match_mode;
/**
* Message Code Match Enable(Msg TLPS). Ensures that a successful
* message Code TLP field comparison match (see Message msg_code)occurs
* (in MSG transactions) for address translation to proceed.
*/
al_bool enable_msg_match_mode;
/**
* USE WITH CAUTION: setting this boolean to AL_TRUE allows setting the
@ -1008,7 +1227,11 @@ void al_pcie_atu_region_get_fields(
/**
* @brief Configure axi io bar.
* every hit to this bar will override size to 4 bytes.
*
* This is an EP feature, enabling PCIe IO transaction to be captured if it fits
* within start and end address, and then mapped to internal 4-byte
* memRead/memWrite. Every hit to this bar will override size to 4 bytes.
*
* @param pcie_port pcie port handle
* @param start the first address of the memory
* @param end the last address of the memory
@ -1028,6 +1251,13 @@ enum al_pcie_legacy_int_type{
AL_PCIE_LEGACY_INTD
};
/* @brief generate FLR_PF_DONE message
* @param pcie_pf pcie pf handle
* @return 0 if no error found
*/
int al_pcie_pf_flr_done_gen(struct al_pcie_pf *pcie_pf);
/**
* @brief generate INTx Assert/DeAssert Message
* @param pcie_pf pcie pf handle
@ -1075,7 +1305,7 @@ al_bool al_pcie_msix_masked(struct al_pcie_pf *pcie_pf);
/******************** Advanced Error Reporting (AER) API **********************/
/**
* @brief configure AER capability
* @brief configure EP physical function AER capability
* @param pcie_pf pcie pf handle
* @param params AER capability configuration parameters
* @return 0 if no error found
@ -1085,7 +1315,7 @@ int al_pcie_aer_config(
struct al_pcie_aer_params *params);
/**
* @brief AER uncorretable errors get and clear
* @brief EP physical function AER uncorrectable errors get and clear
* @param pcie_pf pcie pf handle
* @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for
* details
@ -1093,7 +1323,7 @@ int al_pcie_aer_config(
unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf);
/**
* @brief AER corretable errors get and clear
* @brief EP physical function AER correctable errors get and clear
* @param pcie_pf pcie pf handle
* @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for
* details
@ -1101,7 +1331,8 @@ unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf);
unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf);
/**
* @brief AER get the header for the TLP corresponding to a detected error
* @brief EP physical function AER get the header for
* the TLP corresponding to a detected error
* @param pcie_pf pcie pf handle
* @param hdr pointer to an array for getting the header
*/
@ -1109,6 +1340,44 @@ void al_pcie_aer_err_tlp_hdr_get(
struct al_pcie_pf *pcie_pf,
uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]);
/**
* @brief configure RC port AER capability
* @param pcie_port pcie port handle
* @param params AER capability configuration parameters
* @return 0 if no error found
*/
int al_pcie_port_aer_config(
struct al_pcie_port *pcie_port,
struct al_pcie_aer_params *params);
/**
* @brief RC port AER uncorrectable errors get and clear
* @param pcie_port pcie port handle
* @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for
* details
*/
unsigned int al_pcie_port_aer_uncorr_get_and_clear(
struct al_pcie_port *pcie_port);
/**
* @brief RC port AER correctable errors get and clear
* @param pcie_port pcie port handle
* @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for
* details
*/
unsigned int al_pcie_port_aer_corr_get_and_clear(
struct al_pcie_port *pcie_port);
/**
* @brief RC port AER get the header for
* the TLP corresponding to a detected error
* @param pcie_port pcie port handle
* @param hdr pointer to an array for getting the header
*/
void al_pcie_port_aer_err_tlp_hdr_get(
struct al_pcie_port *pcie_port,
uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]);
/******************** Loop-Back mode (RC and Endpoint modes) ******************/
/**

View File

@ -72,7 +72,7 @@ struct al_pcie_rev1_2_axi_ctrl {
/* [0x28] */
uint32_t dbi_ctl;
/* [0x2c] */
uint32_t vmid_mask;
uint32_t tgtid_mask;
uint32_t rsrvd[4];
};
struct al_pcie_rev3_axi_ctrl {
@ -98,7 +98,7 @@ struct al_pcie_rev3_axi_ctrl {
/* [0x28] */
uint32_t dbi_ctl;
/* [0x2c] */
uint32_t vmid_mask;
uint32_t tgtid_mask;
};
struct al_pcie_rev1_axi_ob_ctrl {
/* [0x0] */
@ -145,10 +145,10 @@ struct al_pcie_rev2_axi_ob_ctrl {
/* [0x24] */
uint32_t msg_limit_h;
/*
* [0x28] this register override the VMID field in the AXUSER [19:4],
* [0x28] this register override the Target-ID field in the AXUSER [19:4],
* for the AXI master port.
*/
uint32_t vmid_reg_ovrd;
uint32_t tgtid_reg_ovrd;
/* [0x2c] this register override the ADDR[63:32] AXI master port. */
uint32_t addr_high_reg_ovrd_value;
/* [0x30] this register override the ADDR[63:32] AXI master port. */
@ -196,10 +196,10 @@ struct al_pcie_rev3_axi_ob_ctrl {
/* [0x40] */
uint32_t aw_msg_addr_mask_h;
/*
* [0x44] this register override the VMID field in the AXUSER [19:4],
* [0x44] this register override the Target-ID field in the AXUSER [19:4],
* for the AXI master port.
*/
uint32_t vmid_reg_ovrd;
uint32_t tgtid_reg_ovrd;
/* [0x48] this register override the ADDR[63:32] AXI master port. */
uint32_t addr_high_reg_ovrd_value;
/* [0x4c] this register override the ADDR[63:32] AXI master port. */
@ -783,9 +783,9 @@ struct al_pcie_rev3_axi_regs {
/* arprot value */
#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_MASK 0x000001C0
#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_SHIFT 6
/* vmid val */
#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_MASK 0x01FFFE00
#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_SHIFT 9
/* tgtid val */
#define PCIE_AXI_CTRL_MASTER_ARCTL_TGTID_VAL_MASK 0x01FFFE00
#define PCIE_AXI_CTRL_MASTER_ARCTL_TGTID_VAL_SHIFT 9
/* IPA value */
#define PCIE_AXI_CTRL_MASTER_ARCTL_IPA_VAL (1 << 25)
/* overide snoop inidcation, if not set take it from mstr_armisc ... */
@ -797,6 +797,7 @@ snoop indication value when override */
arqos value */
#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK 0xF0000000
#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT 28
#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_VAL_MAX 15
/**** Master_Awctl register ****/
/* override arcache */
@ -809,9 +810,9 @@ arqos value */
/* awprot value */
#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_MASK 0x000001C0
#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_SHIFT 6
/* vmid val */
#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_MASK 0x01FFFE00
#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_SHIFT 9
/* tgtid val */
#define PCIE_AXI_CTRL_MASTER_AWCTL_TGTID_VAL_MASK 0x01FFFE00
#define PCIE_AXI_CTRL_MASTER_AWCTL_TGTID_VAL_SHIFT 9
/* IPA value */
#define PCIE_AXI_CTRL_MASTER_AWCTL_IPA_VAL (1 << 25)
/* overide snoop inidcation, if not set take it from mstr_armisc ... */
@ -823,6 +824,7 @@ snoop indication value when override */
awqos value */
#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK 0xF0000000
#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT 28
#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_VAL_MAX 15
/**** slv_ctl register ****/
#define PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN (1 << 6)
@ -888,17 +890,17 @@ awqos value */
#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_MASK 0x000003FF
#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_SHIFT 0
/**** vmid_reg_ovrd register ****/
/**** tgtid_reg_ovrd register ****/
/*
* select if to take the value from register or from address[63:48]:
* 1'b1: register value.
* 1'b0: from address[63:48]
*/
#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_MASK 0x0000FFFF
#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_SHIFT 0
/* vmid override value. */
#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_MASK 0xFFFF0000
#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_SHIFT 16
#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_SEL_MASK 0x0000FFFF
#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_SEL_SHIFT 0
/* tgtid override value. */
#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_VALUE_MASK 0xFFFF0000
#define PCIE_AXI_MISC_OB_CTRL_TGTID_REG_OVRD_VALUE_SHIFT 16
/**** addr_size_replace register ****/
/*
@ -1255,17 +1257,17 @@ awqos value */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_MASK 0x0000C000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_SHIFT 14
/* choose the field from the axuser */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_SHIFT 16
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_AXUSER_SHIFT 16
/* choose the field from register */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_MASK 0x000C0000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_SHIFT 18
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_REG_MASK 0x000C0000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_OVRD_FROM_REG_SHIFT 18
/* in case the field take from the address, offset field for each bit. */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_MASK 0x0FF00000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_SHIFT 20
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_ADDR_OFFSET_MASK 0x0FF00000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_TGTID89_VEC_ADDR_OFFSET_SHIFT 20
/* register value override */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_MASK 0x30000000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_SHIFT 28
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_TGTID89_VEC_OVRD_MASK 0x30000000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_TGTID89_VEC_OVRD_SHIFT 28
/* Rsrvd */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_MASK 0xC0000000
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_SHIFT 30
@ -1291,9 +1293,9 @@ awqos value */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_SHIFT 30
/**** func_ctrl_4 register ****/
/* When set take the corresponding bit address from vmid value. */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_MASK 0x000003FF
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_SHIFT 0
/* When set take the corresponding bit address from tgtid value. */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_TGTID_MASK 0x000003FF
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_TGTID_SHIFT 0
/* override value. */
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_MASK 0x000FFC00
#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_SHIFT 10

View File

@ -81,7 +81,7 @@ enum al_pcie_app_int_grp_a {
/** [RC only] Deassert_INTB received */
AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2),
/**
* [RC only] Deassert_INTA received - there's a didcated GIC interrupt
* [RC only] Deassert_INTA received - there's a dedicated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3),
@ -92,7 +92,7 @@ enum al_pcie_app_int_grp_a {
/** [RC only] Assert_INTB received */
AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6),
/**
* [RC only] Assert_INTA received - there's a didcated GIC interrupt
* [RC only] Assert_INTA received - there's a dedicated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7),
@ -150,13 +150,13 @@ enum al_pcie_app_int_grp_b {
AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* Asserted when a vendor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* Asserted when a vendor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7),
@ -166,7 +166,7 @@ enum al_pcie_app_int_grp_b {
AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13),
/** [RC/EP] OB Vendor message request is granted by the PCIe core */
AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14),
/** [RC only] CPL timeout from the PCIe core indiication */
/** [RC only] CPL timeout from the PCIe core indication */
AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15),
/** [RC/EP] Slave Response Composer Lookup Error */
AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16),

View File

@ -51,18 +51,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "al_hal_pcie_w_reg_ex.h"
#endif
/**
* Revision IDs:
* ID_0: SlickRock M0
* ID_1: SlickRock A0
* ID_2: PeakRock x4
* ID_3: PeakRock x8
*/
#define AL_PCIE_REV_ID_0 0
#define AL_PCIE_REV_ID_1 1
#define AL_PCIE_REV_ID_2 2
#define AL_PCIE_REV_ID_3 3
#define AL_PCIE_AXI_REGS_OFFSET 0x0
#define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000
#define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000
@ -74,6 +62,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define REV3_MAX_NUM_LANES 8
#define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */
/** Number of outbound atu regions - rev 1/2 */
#define AL_PCIE_REV_1_2_ATU_NUM_OUTBOUND_REGIONS 12
/** Number of outbound atu regions - rev 3 */
#define AL_PCIE_REV_3_ATU_NUM_OUTBOUND_REGIONS 16
struct al_pcie_core_iatu_regs {
uint32_t index;
uint32_t cr1;
@ -253,8 +246,10 @@ struct al_pcie_rev3_regs {
struct al_pcie_axi_ctrl {
uint32_t *global;
uint32_t *master_rctl;
uint32_t *master_arctl;
uint32_t *master_awctl;
uint32_t *master_ctl;
uint32_t *slv_ctl;
};
@ -265,6 +260,13 @@ struct al_pcie_axi_ob_ctrl {
uint32_t *io_start_h;
uint32_t *io_limit_l;
uint32_t *io_limit_h;
uint32_t *io_addr_mask_h; /* Rev 3 only */
uint32_t *ar_msg_addr_mask_h; /* Rev 3 only */
uint32_t *aw_msg_addr_mask_h; /* Rev 3 only */
uint32_t *tgtid_reg_ovrd; /* Rev 2/3 only */
uint32_t *addr_high_reg_ovrd_value; /* Rev 2/3 only */
uint32_t *addr_high_reg_ovrd_sel; /* Rev 2/3 only */
uint32_t *addr_size_replace; /* Rev 2/3 only */
};
struct al_pcie_axi_pcie_global {
@ -352,14 +354,23 @@ struct al_pcie_w_global_ctrl {
};
struct al_pcie_w_soc_int {
uint32_t *status_0;
uint32_t *status_1;
uint32_t *status_2;
uint32_t *status_3; /* Rev 2/3 only */
uint32_t *mask_inta_leg_0;
uint32_t *mask_inta_leg_1;
uint32_t *mask_inta_leg_2;
uint32_t *mask_inta_leg_3; /* Rev 2/3 only */
uint32_t *mask_msi_leg_0;
uint32_t *mask_msi_leg_1;
uint32_t *mask_msi_leg_2;
uint32_t *mask_msi_leg_3; /* Rev 2/3 only */
};
struct al_pcie_w_atu {
uint32_t *in_mask_pair;
uint32_t *out_mask_pair;
uint32_t *reg_out_mask; /* Rev 3 only */
};
struct al_pcie_w_regs {
@ -375,6 +386,7 @@ struct al_pcie_w_regs {
struct al_pcie_revx_w_int_grp *int_grp_b;
struct al_pcie_revx_w_int_grp *int_grp_c;
struct al_pcie_revx_w_int_grp *int_grp_d;
struct al_pcie_rev3_w_cfg_func_ext *cfg_func_ext; /* Rev 3 only */
};
struct al_pcie_regs {

View File

@ -1498,7 +1498,7 @@ struct al_pcie_rev3_w_regs {
}
#endif
#endif /* __AL_HAL_PCIE_W_REG_H */
#endif /* __AL_HAL_pcie_w_REG_H */
/** @} end of ... group */

View File

@ -66,10 +66,29 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(generic);
bs_protos(generic_armv4);
uint8_t generic_bs_r_1(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset);
uint16_t generic_bs_r_2(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset);
uint32_t generic_bs_r_4(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset);
void generic_bs_w_1(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, uint8_t value);
void generic_bs_w_2(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, uint16_t value);
void generic_bs_w_4(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, uint32_t value);
void generic_bs_w_8(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, uint64_t value);
#define __UNUSED __attribute__((unused))
@ -79,6 +98,52 @@ extern "C" {
#endif
/* *INDENT-ON* */
/**
* Make sure data will be visible by other masters (other CPUS and DMA).
* usually this is achieved by the ARM DMB instruction.
*/
static void al_data_memory_barrier(void);
static void al_smp_data_memory_barrier(void);
/**
* Make sure data will be visible by DMA masters, no restriction for other cpus
*/
static inline void
al_data_memory_barrier(void)
{
#ifndef __aarch64__
dsb();
#else
dsb(sy);
#endif
}
/**
* Make sure data will be visible in order by other cpus masters.
*/
static inline void
al_smp_data_memory_barrier(void)
{
#ifndef __aarch64__
dmb();
#else
dmb(ish);
#endif
}
/**
* Make sure write data will be visible in order by other cpus masters.
*/
static inline void
al_local_data_memory_barrier(void)
{
#ifndef __aarch64__
dsb();
#else
dsb(sy);
#endif
}
/*
* WMA: This is a hack which allows not modifying the __iomem accessing HAL code.
* On ARMv7, bus_handle holds the information about VA of accessed memory. It
@ -168,50 +233,66 @@ uint64_t al_reg_read64(uint64_t * offset);
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
#define al_reg_write8(l, v) do { \
al_data_memory_barrier(); \
generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); \
al_smp_data_memory_barrier(); \
} while (0)
/**
* Write to MMIO 16 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
#define al_reg_write16(l, v) do { \
al_data_memory_barrier(); \
generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); \
al_smp_data_memory_barrier(); \
} while (0)
/**
* Write to MMIO 32 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
#define al_reg_write32(l, v) do { \
al_data_memory_barrier(); \
generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); \
al_smp_data_memory_barrier(); \
} while (0)
/**
* Write to MMIO 64 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
#define al_reg_write64(l, v) do { \
al_data_memory_barrier(); \
generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); \
al_smp_data_memory_barrier(); \
} while (0)
static inline uint8_t
al_reg_read8(uint8_t *l)
{
dsb();
al_data_memory_barrier();
return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
}
static inline uint16_t
al_reg_read16(uint16_t *l)
{
dsb();
al_data_memory_barrier();
return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
}
static inline uint32_t
al_reg_read32(uint32_t *l)
{
dsb();
al_data_memory_barrier();
return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
}
@ -223,10 +304,8 @@ al_reg_read32(uint32_t *l)
#define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
extern struct mtx al_dbg_lock;
#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock)
#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock)
#define AL_DBG_LOCK()
#define AL_DBG_UNLOCK()
/**
* print message
@ -277,39 +356,6 @@ extern struct mtx al_dbg_lock;
__FILE__, __LINE__, __func__, #COND); \
} while(AL_FALSE)
/**
* Make sure data will be visible by other masters (other CPUS and DMA).
* usually this is achieved by the ARM DMB instruction.
*/
static void al_data_memory_barrier(void);
/**
* Make sure data will be visible by DMA masters, no restriction for other cpus
*/
static inline void
al_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure data will be visible in order by other cpus masters.
*/
static inline void
al_smp_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure write data will be visible in order by other cpus masters.
*/
static inline void
al_local_data_memory_barrier(void)
{
dsb();
}
/**
* al_udelay - micro sec delay
*/

View File

@ -60,24 +60,6 @@ typedef int al_bool; /** boolean */
#define AL_TRUE 1
#define AL_FALSE 0
/* define types */
#ifndef AL_HAVE_TYPES
typedef unsigned char uint8_t; /** unsigned 8 bits */
typedef unsigned short uint16_t; /** unsigned 16 bits */
typedef unsigned int uint32_t; /** unsigned 32 bits */
typedef unsigned long long uint64_t; /** unsigned 64 bits */
typedef signed char int8_t; /** signed 8 bits */
typedef short int int16_t; /** signed 16 bits */
typedef signed int int32_t; /** signed 32 bits */
/** An unsigned int that is guaranteed to be the same size as a pointer */
/** C99 standard */
typedef unsigned long uintptr_t;
#endif
/** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */
typedef uint64_t al_phys_addr_t;

View File

@ -57,6 +57,7 @@ extern "C" {
/* *INDENT-ON* */
#define AL_BIT(b) (1UL << (b))
#define AL_BIT_64(b) (1ULL << (b))
#define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x)))
#define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes_25g.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_25G_H__
#define __AL_HAL_SERDES_25G_H__
#include "al_hal_common.h"
#include "al_hal_serdes_interface.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
int al_serdes_25g_handle_init(
void __iomem *serdes_regs_base,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_SRDS__ */
/** @} end of SERDES group */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,434 @@
/*******************************************************************************
Copyright (C) 2013 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 or V3 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_serdes_c_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_serdes_c_REGS_H__
#define __AL_HAL_serdes_c_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct al_serdes_c_gen {
/* [0x0] SERDES registers Version */
uint32_t version;
uint32_t rsrvd_0[3];
/* [0x10] SERDES register file address */
uint32_t reg_addr;
/* [0x14] SERDES register file data */
uint32_t reg_data;
/* [0x18] SERDES control */
uint32_t ctrl;
/* [0x1c] SERDES cpu mem address */
uint32_t cpu_prog_addr;
/* [0x20] SERDES cpu mem data */
uint32_t cpu_prog_data;
/* [0x24] SERDES data mem address */
uint32_t cpu_data_mem_addr;
/* [0x28] SERDES data mem data */
uint32_t cpu_data_mem_data;
/* [0x2c] SERDES control */
uint32_t rst;
/* [0x30] SERDES control */
uint32_t status;
uint32_t rsrvd[51];
};
struct al_serdes_c_lane {
uint32_t rsrvd_0[4];
/* [0x10] Data configuration */
uint32_t cfg;
/* [0x14] Lane status */
uint32_t stat;
/* [0x18] SERDES control */
uint32_t reserved;
uint32_t rsrvd[25];
};
struct al_serdes_c_regs {
uint32_t rsrvd_0[64];
struct al_serdes_c_gen gen; /* [0x100] */
struct al_serdes_c_lane lane[2]; /* [0x200] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* date of release */
#define SERDES_C_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define SERDES_C_GEN_VERSION_DATE_DAY_SHIFT 16
/* month of release */
#define SERDES_C_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define SERDES_C_GEN_VERSION_DATA_MONTH_SHIFT 21
/* year of release (starting from 2000) */
#define SERDES_C_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define SERDES_C_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define SERDES_C_GEN_VERSION_RESERVED_MASK 0xC0000000
#define SERDES_C_GEN_VERSION_RESERVED_SHIFT 30
/**** reg_addr register ****/
/* address value */
#define SERDES_C_GEN_REG_ADDR_VAL_MASK 0x00007FFF
#define SERDES_C_GEN_REG_ADDR_VAL_SHIFT 0
/**** reg_data register ****/
/* data value */
#define SERDES_C_GEN_REG_DATA_VAL_MASK 0x000000FF
#define SERDES_C_GEN_REG_DATA_VAL_SHIFT 0
/* Bit-wise write enable */
#define SERDES_C_GEN_REG_DATA_STRB_MASK 0x0000FF00
#define SERDES_C_GEN_REG_DATA_STRB_SHIFT 8
/**** ctrl register ****/
/*
* 0x0 Select reference clock from Bump
* 0x1 Select inter-macro reference clock from the left side
* 0x2 Same as 0x0
* 0x3 Select inter-macro reference clock from the right side
*/
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_MASK 0x00000003
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT 0
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_REF \
(0 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_L2R \
(1 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_R2L \
(3 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
/*
* 0x0 Tied to 0 to save power
* 0x1 Select reference clock from Bump
* 0x2 Select inter-macro reference clock input from right side
* 0x3 Same as 0x2
*/
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_MASK 0x00000030
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT 4
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_0 \
(0 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_REF \
(1 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_R2L \
(2 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
/*
* 0x0 Tied to 0 to save power
* 0x1 Select reference clock from Bump
* 0x2 Select inter-macro reference clock input from left side
* 0x3 Same as 0x2
*/
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_MASK 0x000000C0
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT 6
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_0 \
(0 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_REF \
(1 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_L2R \
(2 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
/*
* Program memory acknowledge - Only when the access
* to the program memory is not
* ready for the microcontroller, it
* is driven to 0
*/
#define SERDES_C_GEN_CTRL_CPU_MEMPSACK (1 << 8)
/*
* Data memory acknowledge - Only when the access
* to the program memory is not
* ready for the microcontroller, it
* is driven to 0
*/
#define SERDES_C_GEN_CTRL_CPU_MEMACK (1 << 12)
/*
* 0 - keep cpu clk as sb clk
* 1 cpu_clk is sb_clk divided by 2
*/
#define SERDES_C_GEN_CTRL_CPU_CLK_DIV (1 << 16)
/*
* 0x0 OIF CEI-28G-SR
* 0x1 OIF CIE-25G-LR
* 0x8 XFI
* Others Reserved
*
* Note that phy_ctrl_cfg_i[3] is used to signify high-speed/low-speed
*/
#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_MASK 0x00F00000
#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_SHIFT 20
/*
* 0 - Internal 8051 micro- controller is allowed to access the internal APB
* CSR. Internal APB runs at cpu_clk_i, and the accesses from the external APB
* in apb_clk_i domain to APB CSR are resynchronized to cpu_clk_i. 1 Bypass
* CPU. Internal 8051 micro-controller is blocked from accessing the internal
* APB CSR. Internal APB runs at apb_clk_i.
*/
#define SERDES_C_GEN_CTRL_CPU_BYPASS (1 << 24)
/**** cpu_prog_addr register ****/
/*
* address value 32 bit,
* The firmware data will be 1 byte with 64K rows
*/
#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_MASK 0x00007FFF
#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_SHIFT 0
/**** cpu_data_mem_addr register ****/
/* address value 8K byte memory */
#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_MASK 0x00001FFF
#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_SHIFT 0
/**** cpu_data_mem_data register ****/
/* data value */
#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_MASK 0x000000FF
#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_SHIFT 0
/**** rst register ****/
/* Power on reset Signal active low */
#define SERDES_C_GEN_RST_POR_N (1 << 0)
/* CMU reset Active low */
#define SERDES_C_GEN_RST_CM0_RST_N (1 << 1)
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Near complete power down (only
* refclk buffers and portions of analog bias
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when CMU is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* effect in power on reset state.
*/
#define SERDES_C_GEN_RST_CM0_PD_MASK 0x00000030
#define SERDES_C_GEN_RST_CM0_PD_SHIFT 4
/* Lane0 reset signal active low */
#define SERDES_C_GEN_RST_LN0_RST_N (1 << 6)
/* Lane1 reset signal active low */
#define SERDES_C_GEN_RST_LN1_RST_N (1 << 7)
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Most blocks powered down (only LOS
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when Lane is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* affect in power on reset state
*/
#define SERDES_C_GEN_RST_LN0_PD_MASK 0x00000300
#define SERDES_C_GEN_RST_LN0_PD_SHIFT 8
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Most blocks powered down (only LOS
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when Lane is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* affect in power on reset state
*/
#define SERDES_C_GEN_RST_LN1_PD_MASK 0x00000C00
#define SERDES_C_GEN_RST_LN1_PD_SHIFT 10
#define SERDES_C_GEN_RST_CPU_MEM_RESET (1 << 12)
#define SERDES_C_GEN_RST_CPU_MEM_SHUTDOWN (1 << 13)
#define SERDES_C_GEN_RST_CAPRI_APB_RESET (1 << 14)
/**** status register ****/
/*
* 0x0 No error
* 0x1 PHY has an internal error
*/
#define SERDES_C_GEN_STATUS_ERR_O (1 << 0)
/*
* 0x0 PHY is not ready to respond to
* cm0_rst_n_i and cm0_pd_i[1:0]. The
* signals should not be changed.
* 0x1 - PHY is ready to respond to
* cm0_rst_n_i and cm0_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_CM0_RST_PD_READY (1 << 1)
/*
* Indicates CMU PLL has locked to the
* reference clock and all output clocks are at
* the correct frequency
*/
#define SERDES_C_GEN_STATUS_CM0_OK_O (1 << 2)
/*
* 0x0 PHY is not ready to respond to
* ln0_rst_n and ln0_pd[1:0]. The signals
* should not be changed.
* 0x1 - PHY is ready to respond to lnX_rst_n_i
* and lnX_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_LN0_RST_PD_READY (1 << 3)
/*
* 0x0 PHY is not ready to respond to
* ln1_rst_n_i and ln1_pd[1:0]. The signals
* should not be changed.
* 0x1 - PHY is ready to respond to lnX_rst_n_i
* and lnX_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_LN1_RST_PD_READY (1 << 4)
/*
* Active low when the CPU performs a wait cycle (internally or externally
* generated)
*/
#define SERDES_C_GEN_STATUS_CPU_WAITSTATE (1 << 5)
#define SERDES_C_GEN_STATUS_TBUS_MASK 0x000FFF00
#define SERDES_C_GEN_STATUS_TBUS_SHIFT 8
/**** cfg register ****/
/* 1- Swap 32 bit data on RX side */
#define SERDES_C_LANE_CFG_RX_LANE_SWAP (1 << 0)
/* 1- Swap 32 bit data on TX side */
#define SERDES_C_LANE_CFG_TX_LANE_SWAP (1 << 1)
/* 1 invert rx data polarity */
#define SERDES_C_LANE_CFG_LN_CTRL_RXPOLARITY (1 << 2)
/* 1 invert tx data polarity */
#define SERDES_C_LANE_CFG_TX_LANE_POLARITY (1 << 3)
/*
* 0x0 Data on lnX_txdata_o will not be
* transmitted. Transmitter will be placed into
* electrical idle.
* 0x1 Data on the active bits of
* lnX_txdata_o will be transmitted
*/
#define SERDES_C_LANE_CFG_LN_CTRL_TX_EN (1 << 4)
/*
* Informs the PHY to bypass the output of the
* analog LOS detector and instead rely upon
* a protocol LOS mechanism in the SoC/ASIC
* 0x0 LOS operates as normal
* 0x1 Bypass analog LOS output and
* instead rely upon protocol-level LOS
* detection via input lnX_ctrl_los_eii_value
*/
#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_EN (1 << 5)
/*
* If lnX_ctrl_los_eii_en_i = 1 then Informs
* the PHY that the received signal was lost
*/
#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_VALUE (1 << 6)
/* One hot mux */
#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_MASK 0x00000F00
#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_SHIFT 8
/* 0x0 - 20-bit 0x1 40-bit */
#define SERDES_C_LANE_CFG_LN_CTRL_DATA_WIDTH (1 << 12)
/**** stat register ****/
/*
* x0 lane is not ready to send and receive data
* 0x1 lane is ready to send and receive data
*/
#define SERDES_C_LANE_STAT_LNX_STAT_OK (1 << 0)
/*
* 0x0 received data run length has not
* exceed the programmable run length
* detector threshold
* 0x1 received data run length has
* exceeded the programmable run length
* detector threshold
*/
#define SERDES_C_LANE_STAT_LN_STAT_RUNLEN_ERR (1 << 1)
/*
* 0x0 data on lnX_rxdata_o are invalid
* 0x1 data on the active bits of
* lnX_rxdata_o are valid
*/
#define SERDES_C_LANE_STAT_LN_STAT_RXVALID (1 << 2)
/*
* Loss of Signal (LOS) indicator that includes
* the combined functions of the digitally
* assisted analog LOS, digital LOS, and
* protocol LOS override features
* 0x0 Signal detected on lnX_rxp_i /
* lnX_rxm_i pins
* 0x1 No signal detected on lnX_rxp_i /
* lnX_rxm_i pins
*/
#define SERDES_C_LANE_STAT_LN_STAT_LOS (1 << 3)
#define SERDES_C_LANE_STAT_LN_STAT_LOS_DEGLITCH (1 << 4)
/**** reserved register ****/
#define SERDES_C_LANE_RESERVED_DEF_0_MASK 0x0000FFFF
#define SERDES_C_LANE_RESERVED_DEF_0_SHIFT 0
#define SERDES_C_LANE_RESERVED_DEF_1_MASK 0xFFFF0000
#define SERDES_C_LANE_RESERVED_DEF_1_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_serdes_c_REGS_H__ */
/** @} end of ... group */

View File

@ -0,0 +1,87 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_H__
#define __AL_HAL_SERDES_H__
#include "al_hal_common.h"
#include "al_hal_serdes_interface.h"
#include "al_hal_serdes_hssp_regs.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* Initializes a SERDES group object
*
* @param serdes_regs_base
* The SERDES register file base pointer
*
* @param obj
* An allocated, non initialized object context
*
* @return 0 if no error found.
*
*/
int al_serdes_hssp_handle_init(
void __iomem *serdes_regs_base,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_SRDS__ */
/** @} end of SERDES group */

View File

@ -0,0 +1,749 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_SERDES_INTERNAL_REGS_H__
#define __AL_SERDES_INTERNAL_REGS_H__
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Per lane register fields
******************************************************************************/
/*
* RX and TX lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT 0x01
/*
* RX and TX lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS 0x02
/* RX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM 3
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0 0x10
/* TX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM 4
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0 0x10
/* RX lane word width */
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_10 0x01
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_16 0x02
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 0x03
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_32 0x04
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_40 0x05
/* TX lane word width */
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_10 0x10
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_16 0x20
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20 0x30
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_32 0x40
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_40 0x50
/* RX lane rate select */
#define SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSRX_DIVRATE_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4 0x01
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2 0x02
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1 0x03
/* TX lane rate select */
#define SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSTX_DIVRATE_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4 0x10
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2 0x20
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1 0x30
/*
* PMA serial RX-to-TX loop-back enable (from AGC to IO Driver). Serial receive
* to transmit loopback: 0 - Disables loopback 1 - Transmits the untimed,
* partial equalized RX signal out the transmit IO pins
*/
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN 0x10
/*
* PMA TX-to-RX buffered serial loop-back enable (bypasses IO Driver). Serial
* transmit to receive buffered loopback: 0 - Disables loopback 1 - Loops back
* the TX serializer output into the CDR
*/
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN 0x20
/*
* PMA TX-to-RX I/O serial loop-back enable (loop back done directly from TX to
* RX pads). Serial IO loopback from the transmit lane IO pins to the receive
* lane IO pins: 0 - Disables loopback 1 - Loops back the driver IO signal to
* the RX IO pins
*/
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN 0x40
/*
* PMA Parallel RX-to-TX loop-back enable. Parallel loopback from the PMA
* receive lane 20-bit data ports, to the transmit lane 20-bit data ports 0 -
* Disables loopback 1 - Loops back the 20-bit receive data port to the
* transmitter
*/
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN 0x80
/*
* PMA CDR recovered-clock loopback enable; asserted when PARRX2TXTIMEDEN is 1.
* Transmit bit clock select: 0 - Selects synthesizer bit clock for transmit 1
* - Selects CDR clock for transmit
*/
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN 0x01
/* Receive lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSRXBIST_EN 0x01
/* TX lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSTXBIST_EN 0x02
/*
* RX BIST completion signal 0 - Indicates test is not completed 1 - Indicates
* the test has completed, and will remain high until a new test is initiated
*/
#define SERDES_IREG_FLD_RXBIST_DONE_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_DONE 0x04
/*
* RX BIST error count overflow indicator. Indicates an overflow in the number
* of byte errors identified during the course of the test. This word is stable
* to sample when *_DONE_* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW 0x08
/*
* RX BIST locked indicator 0 - Indicates BIST is not word locked and error
* comparisons have not begun yet 1 - Indicates BIST is word locked and error
* comparisons have begun
*/
#define SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_RXLOCKED 0x10
/*
* RX BIST error count word. Indicates the number of byte errors identified
* during the course of the test. This word is stable to sample when *_DONE_*
* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM 9
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM 10
/* Tx params */
#define SERDES_IREG_TX_DRV_1_REG_NUM 21
#define SERDES_IREG_TX_DRV_1_HLEV_MASK 0x7
#define SERDES_IREG_TX_DRV_1_HLEV_SHIFT 0
#define SERDES_IREG_TX_DRV_1_LEVN_MASK 0xf8
#define SERDES_IREG_TX_DRV_1_LEVN_SHIFT 3
#define SERDES_IREG_TX_DRV_2_REG_NUM 22
#define SERDES_IREG_TX_DRV_2_LEVNM1_MASK 0xf
#define SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT 0
#define SERDES_IREG_TX_DRV_2_LEVNM2_MASK 0x30
#define SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT 4
#define SERDES_IREG_TX_DRV_3_REG_NUM 23
#define SERDES_IREG_TX_DRV_3_LEVNP1_MASK 0x7
#define SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT 0
#define SERDES_IREG_TX_DRV_3_SLEW_MASK 0x18
#define SERDES_IREG_TX_DRV_3_SLEW_SHIFT 3
/* Rx params */
#define SERDES_IREG_RX_CALEQ_1_REG_NUM 24
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT 0
/* DFE post-shaping tap 3dB frequency */
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK 0x38
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT 3
#define SERDES_IREG_RX_CALEQ_2_REG_NUM 25
/* DFE post-shaping tap gain */
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT 0
/* DFE first tap gain control */
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK 0x78
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT 3
#define SERDES_IREG_RX_CALEQ_3_REG_NUM 26
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK 0xf0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_4_REG_NUM 27
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK 0x70
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_5_REG_NUM 28
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK 0x7
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT 0
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK 0xf8
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT 3
/* RX lane best eye point measurement result */
#define SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM 29
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM 30
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK 0x3F
/*
* Adaptive RX Equalization enable
* 0 - Disables adaptive RX equalization.
* 1 - Enables adaptive RX equalization.
*/
#define SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM 31
#define SERDES_IREG_FLD_PCSRXEQ_START (1 << 0)
/*
* Enables an eye diagram measurement
* within the PHY.
* 0 - Disables eye diagram measurement
* 1 - Enables eye diagram measurement
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM 31
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START (1 << 1)
/*
* RX lane single roam eye point measurement start signal.
* If asserted, single measurement at fix XADJUST and YADJUST is started.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM 31
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START (1 << 2)
/*
* PHY Eye diagram measurement status
* signal
* 0 - Indicates eye diagram results are not
* valid for sampling
* 1 - Indicates eye diagram is complete and
* results are valid for sampling
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE (1 << 0)
/*
* Eye diagram error signal. Indicates if the
* measurement was invalid because the eye
* diagram was interrupted by the link entering
* electrical idle.
* 0 - Indicates eye diagram is valid
* 1- Indicates an error occurred, and the eye
* diagram measurement should be re-run
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR (1 << 1)
/*
* PHY Adaptive Equalization status
* 0 - Indicates Adaptive Equalization results are not valid for sampling
* 1 - Indicates Adaptive Equalization is complete and results are valid for
* sampling
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE (1 << 2)
/*
*
* PHY Adaptive Equalization Status Signal
* 0 Indicates adaptive equalization results
* are not valid for sampling
* 1 Indicates adaptive equalization is
* complete and results are valid for sampling.
*/
#define SERDES_IREG_FLD_RXEQ_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_DONE (1 << 3)
/*
* 7-bit eye diagram time adjust control
* - 6-bits per UI
* - spans 2 UI
*/
#define SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM 33
/* 6-bit eye diagram voltage adjust control - spans +/-300mVdiff */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM 34
/*
* Eye diagram status signal. Safe for
* sampling when *DONE* signal has
* asserted
* 14'h0000 - Completely Closed Eye
* 14'hFFFF - Completely Open Eye
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM 35
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_MAKE 0xFF
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM 36
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE 0x3F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_SHIFT 0
/*
* RX lane single roam eye point measurement result.
* If 0, eye is open at current XADJUST and YADJUST settings.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM 37
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM 38
/*
* Override enable for CDR lock to reference clock
* 0 - CDR is always locked to reference
* 1 - CDR operation mode (Lock2Reference or Lock2data are controlled internally
* depending on the incoming signal and ppm status)
*/
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM 39
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN (1 << 1)
/*
* Selects Eye to capture based on edge
* 0 - Capture 1st Eye in Eye Diagram
* 1 - Capture 2nd Eye in Eye Diagram measurement
*/
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM 39
#define SERDES_IREG_FLD_RXROAM_XORBITSEL (1 << 2)
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_1ST 0
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND (1 << 2)
/*
* RX Signal detect. 0 indicates no signal, 1 indicates signal detected.
*/
#define SERDES_IREG_FLD_RXRANDET_REG_NUM 41
#define SERDES_IREG_FLD_RXRANDET_STAT 0x20
/*
* RX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_RX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_RX_INV (1 << 0)
/*
* TX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_TX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_TX_INV (1 << 1)
/* LANEPCSPSTATE* override enable (Active low) */
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN (1 << 0)
/* LB* override enable (Active low) */
#define SERDES_IREG_FLD_LB_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LB_LOCWREN (1 << 1)
/* PCSRX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRX_LOCWREN (1 << 4)
/* PCSRXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN (1 << 5)
/* PCSRXEQ* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN (1 << 6)
/* PCSTX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSTX_LOCWREN (1 << 7)
/*
* group registers:
* SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN,
* SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN
* SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN
*/
#define SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM 86
/* PCSTXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN (1 << 0)
/* Override RX_CALCEQ through the internal registers (Active low) */
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM 86
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN (1 << 3)
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN (1 << 4)
/* RXCALROAMEYEMEASIN* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN (1 << 6)
/* RXCALROAMXADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN (1 << 7)
/* RXCALROAMYADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN (1 << 0)
/* RXCDRCALFOSC* override enable. Active Low */
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN (1 << 1)
/* Over-write enable for RXEYEDIAGFSM_INITXVAL */
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN (1 << 2)
/* Over-write enable for CMNCLKGENMUXSEL_TXINTERNAL */
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN (1 << 3)
/* TXCALTCLKDUTY* override enable. Active Low */
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN (1 << 4)
/* Override TX_DRV through the internal registers (Active low) */
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM 87
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN (1 << 5)
/*******************************************************************************
* Common lane register fields - PMA
******************************************************************************/
/*
* Common lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS 0x01
/*
* Common lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT 0x02
/* Synth power state control */
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM 3
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK 0x1f
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD 0x01
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2 0x02
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1 0x04
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S 0x08
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0 0x10
/* Transmit datapath FIFO enable (Active High) */
#define SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM 8
#define SERDES_IREG_FLD_CMNPCS_TXENABLE (1 << 2)
/*
* RX lost of signal detector enable
* - 0 - disable
* - 1 - enable
*/
#define SERDES_IREG_FLD_RXLOSDET_ENABLE_REG_NUM 13
#define SERDES_IREG_FLD_RXLOSDET_ENABLE AL_BIT(4)
/* Signal Detect Threshold Level */
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_MASK AL_FIELD_MASK(2, 0)
/* LOS Detect Threshold Level */
#define SERDES_IREG_FLD_RXLOSDET_THRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXLOSDET_THRESH_MASK AL_FIELD_MASK(4, 3)
#define SERDES_IREG_FLD_RXLOSDET_THRESH_SHIFT 3
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM 30
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM 31
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM 34
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM 36
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM 37
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM 43
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT 0
#define SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(byte_num) (56 + (byte_num))
#define SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES 10
/*
* Selects the transmit BIST mode:
* 0 - Uses the 80-bit internal memory pattern (w/ OOB)
* 1 - Uses a 27 PRBS pattern
* 2 - Uses a 223 PRBS pattern
* 3 - Uses a 231 PRBS pattern
* 4 - Uses a 1010 clock pattern
* 5 and above - Reserved
*/
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM 80
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK 0x07
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER 0x00
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7 0x01
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23 0x02
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31 0x03
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010 0x04
/* Single-Bit error injection enable (on posedge) */
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM 80
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN 0x20
/* CMNPCIEGEN3* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN (1 << 2)
/* CMNPCS* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCS_LOCWREN (1 << 3)
/* CMNPCSBIST* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN (1 << 4)
/* CMNPCSPSTATE* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN (1 << 5)
/* PCS_EN* override enable (Active Low) */
#define SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM 96
#define SERDES_IREG_FLD_PCS_LOCWREN (1 << 3)
/* Eye diagram sample count */
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM 150
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT 0
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM 151
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT 0
/* override control */
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM 230
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN 1 << 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM 623
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM 624
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT 0
/* X and Y coefficient return value */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM 626
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_MASK 0xF0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_SHIFT 4
/* X coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM 627
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT 0
/* X fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM 628
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT 0
/* Y coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM 629
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT 0
/* Y fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM 630
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT 0
#define SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM 157
#define SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM 158
#define SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM 159
#define SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM 160
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM 163
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM 164
/*******************************************************************************
* Common lane register fields - PCS
******************************************************************************/
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM 3
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK AL_FIELD_MASK(5, 4)
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT 4
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM 6
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA AL_BIT(2)
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM 18
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM 19
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM 20
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM 21
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_REG_NUM 23
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_REG_NUM 24
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_REG_NUM 35
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_MASK 0x1f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_REG_NUM 37
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_MASK 0xe0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_SHIFT 5
#ifdef __cplusplus
}
#endif
#endif /* __AL_serdes_REG_H */

View File

@ -0,0 +1,494 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_serdes_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_SERDES_REGS_H__
#define __AL_HAL_SERDES_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct serdes_gen {
/* [0x0] SerDes Registers Version */
uint32_t version;
uint32_t rsrvd_0[3];
/* [0x10] SerDes register file address */
uint32_t reg_addr;
/* [0x14] SerDes register file data */
uint32_t reg_data;
uint32_t rsrvd_1[2];
/* [0x20] SerDes control */
uint32_t ictl_multi_bist;
/* [0x24] SerDes control */
uint32_t ictl_pcs;
/* [0x28] SerDes control */
uint32_t ictl_pma;
uint32_t rsrvd_2;
/* [0x30] SerDes control */
uint32_t ipd_multi_synth;
/* [0x34] SerDes control */
uint32_t irst;
/* [0x38] SerDes control */
uint32_t octl_multi_synthready;
/* [0x3c] SerDes control */
uint32_t octl_multi_synthstatus;
/* [0x40] SerDes control */
uint32_t clk_out;
uint32_t rsrvd[47];
};
struct serdes_lane {
uint32_t rsrvd1[4];
/* [0x10] SerDes status */
uint32_t octl_pma;
/* [0x14] SerDes control */
uint32_t ictl_multi_andme;
/* [0x18] SerDes control */
uint32_t ictl_multi_lb;
/* [0x1c] SerDes control */
uint32_t ictl_multi_rxbist;
/* [0x20] SerDes control */
uint32_t ictl_multi_txbist;
/* [0x24] SerDes control */
uint32_t ictl_multi;
/* [0x28] SerDes control */
uint32_t ictl_multi_rxeq;
/* [0x2c] SerDes control */
uint32_t ictl_multi_rxeq_l_low;
/* [0x30] SerDes control */
uint32_t ictl_multi_rxeq_l_high;
/* [0x34] SerDes control */
uint32_t ictl_multi_rxeyediag;
/* [0x38] SerDes control */
uint32_t ictl_multi_txdeemph;
/* [0x3c] SerDes control */
uint32_t ictl_multi_txmargin;
/* [0x40] SerDes control */
uint32_t ictl_multi_txswing;
/* [0x44] SerDes control */
uint32_t idat_multi;
/* [0x48] SerDes control */
uint32_t ipd_multi;
/* [0x4c] SerDes control */
uint32_t octl_multi_rxbist;
/* [0x50] SerDes control */
uint32_t octl_multi;
/* [0x54] SerDes control */
uint32_t octl_multi_rxeyediag;
/* [0x58] SerDes control */
uint32_t odat_multi_rxbist;
/* [0x5c] SerDes control */
uint32_t odat_multi_rxeq;
/* [0x60] SerDes control */
uint32_t multi_rx_dvalid;
/* [0x64] SerDes control */
uint32_t reserved;
uint32_t rsrvd[6];
};
struct al_serdes_regs {
uint32_t rsrvd_0[64];
struct serdes_gen gen; /* [0x100] */
struct serdes_lane lane[4]; /* [0x200] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* Date of release */
#define SERDES_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define SERDES_GEN_VERSION_DATE_DAY_SHIFT 16
/* Month of release */
#define SERDES_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define SERDES_GEN_VERSION_DATA_MONTH_SHIFT 21
/* Year of release (starting from 2000) */
#define SERDES_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define SERDES_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define SERDES_GEN_VERSION_RESERVED_MASK 0xC0000000
#define SERDES_GEN_VERSION_RESERVED_SHIFT 30
/**** reg_addr register ****/
/* Address value */
#define SERDES_GEN_REG_ADDR_VAL_MASK 0x0000FFFF
#define SERDES_GEN_REG_ADDR_VAL_SHIFT 0
/**** reg_data register ****/
/* Data value */
#define SERDES_GEN_REG_DATA_VAL_MASK 0x000000FF
#define SERDES_GEN_REG_DATA_VAL_SHIFT 0
/**** ICTL_MULTI_BIST register ****/
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_SHIFT 0
/**** ICTL_PCS register ****/
#define SERDES_GEN_ICTL_PCS_EN_NT (1 << 0)
/**** ICTL_PMA register ****/
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT 0
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_REF \
(0 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_L2R \
(4 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_MASK 0x00000070
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT 4
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_MASK 0x00000700
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT 8
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_L2R \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_THIS (0 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_MASTER (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A (1 << 12)
#define SERDES_GEN_ICTL_PMA_SYNTHCKBYPASSEN_NT (1 << 13)
/**** IPD_MULTI_SYNTH register ****/
#define SERDES_GEN_IPD_MULTI_SYNTH_B (1 << 0)
/**** IRST register ****/
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A (1 << 0)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A (1 << 1)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A (1 << 2)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A (1 << 3)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A (1 << 4)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A (1 << 5)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A (1 << 6)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A (1 << 7)
#define SERDES_GEN_IRST_MULTI_HARD_SYNTH_B_A (1 << 8)
#define SERDES_GEN_IRST_POR_B_A (1 << 12)
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A_SEL (1 << 16)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A_SEL (1 << 17)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A_SEL (1 << 18)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL (1 << 19)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A_SEL (1 << 20)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A_SEL (1 << 21)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A_SEL (1 << 22)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A_SEL (1 << 23)
/**** OCTL_MULTI_SYNTHREADY register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHREADY_A (1 << 0)
/**** OCTL_MULTI_SYNTHSTATUS register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHSTATUS_A (1 << 0)
/**** clk_out register ****/
#define SERDES_GEN_CLK_OUT_SEL_MASK 0x0000003F
#define SERDES_GEN_CLK_OUT_SEL_SHIFT 0
/**** OCTL_PMA register ****/
#define SERDES_LANE_OCTL_PMA_TXSTATUS_L_A (1 << 0)
/**** ICTL_MULTI_ANDME register ****/
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A (1 << 0)
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A_SEL (1 << 1)
/**** ICTL_MULTI_LB register ****/
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXIOTIMEDEN_L_NT (1 << 0)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT (1 << 1)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT (1 << 2)
#define SERDES_LANE_ICTL_MULTI_LB_PARRX2TXTIMEDEN_L_NT (1 << 3)
#define SERDES_LANE_ICTL_MULTI_LB_CDRCLK2TXEN_L_NT (1 << 4)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT_SEL (1 << 8)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT_SEL (1 << 9)
/**** ICTL_MULTI_RXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_RXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI_TXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_TXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI register ****/
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_MASK 0x00000003
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SEL (1 << 2)
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_SHIFT 4
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATAEN_L_A (1 << 8)
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATA_L_A (1 << 9)
#define SERDES_LANE_ICTL_MULTI_TXBEACON_L_A (1 << 12)
#define SERDES_LANE_ICTL_MULTI_TXDETECTRXREQ_L_A (1 << 13)
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_MASK 0x00070000
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SHIFT 16
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SEL (1 << 19)
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_MASK 0x00700000
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SHIFT 20
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SEL (1 << 23)
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_MASK 0x07000000
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_SHIFT 24
#define SERDES_LANE_ICTL_MULTI_TXAMP_EN_L (1 << 27)
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_MASK 0x70000000
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_SHIFT 28
/**** ICTL_MULTI_RXEQ register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_EN_L (1 << 0)
#define SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A (1 << 1)
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_SHIFT 4
/**** ICTL_MULTI_RXEQ_L_high register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_L_HIGH_VAL (1 << 0)
/**** ICTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_ICTL_MULTI_RXEYEDIAG_START_L_A (1 << 0)
/**** ICTL_MULTI_TXDEEMPH register ****/
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_MASK 0x0003FFFF
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_MASK 0x7c0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_SHIFT 6
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_MASK 0xf000
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_SHIFT 12
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_MASK 0x7
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_SHIFT 0
/**** ICTL_MULTI_TXMARGIN register ****/
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_MASK 0x00000007
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_SHIFT 0
/**** ICTL_MULTI_TXSWING register ****/
#define SERDES_LANE_ICTL_MULTI_TXSWING_L (1 << 0)
/**** IDAT_MULTI register ****/
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_MASK 0x0000000F
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SHIFT 0
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SEL (1 << 4)
/**** IPD_MULTI register ****/
#define SERDES_LANE_IPD_MULTI_TX_L_B (1 << 0)
#define SERDES_LANE_IPD_MULTI_RX_L_B (1 << 1)
/**** OCTL_MULTI_RXBIST register ****/
#define SERDES_LANE_OCTL_MULTI_RXBIST_DONE_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXBIST_RXLOCKED_L_A (1 << 1)
/**** OCTL_MULTI register ****/
#define SERDES_LANE_OCTL_MULTI_RXCDRLOCK2DATA_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A (1 << 1)
#define SERDES_LANE_OCTL_MULTI_RXREADY_L_A (1 << 2)
#define SERDES_LANE_OCTL_MULTI_RXSTATUS_L_A (1 << 3)
#define SERDES_LANE_OCTL_MULTI_TXREADY_L_A (1 << 4)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXSTAT_L_A (1 << 5)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXACK_L_A (1 << 6)
#define SERDES_LANE_OCTL_MULTI_RXSIGNALDETECT_L_A (1 << 7)
/**** OCTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_MASK 0x00003FFF
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_SHIFT 0
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_DONE_L_A (1 << 16)
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_ERR_L_A (1 << 17)
/**** ODAT_MULTI_RXBIST register ****/
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_MASK 0x0000FFFF
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_SHIFT 0
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_OVERFLOW_L_A (1 << 16)
/**** ODAT_MULTI_RXEQ register ****/
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_MASK 0x00003FFF
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_SHIFT 0
/**** MULTI_RX_DVALID register ****/
#define SERDES_LANE_MULTI_RX_DVALID_MASK_CDR_LOCK (1 << 0)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SIGNALDETECT (1 << 1)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_TX_READY (1 << 2)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_READY (1 << 3)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SYNT_READY (1 << 4)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_ELECIDLE (1 << 5)
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_MASK 0x00FF0000
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_SHIFT 16
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_SEL (1 << 24)
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_VAL (1 << 25)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_SEL (1 << 26)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_VAL (1 << 27)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_SEL (1 << 28)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_VAL (1 << 29)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_SEL (1 << 30)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_VAL (1 << 31)
/**** reserved register ****/
#define SERDES_LANE_RESERVED_OUT_MASK 0x000000FF
#define SERDES_LANE_RESERVED_OUT_SHIFT 0
#define SERDES_LANE_RESERVED_IN_MASK 0x00FF0000
#define SERDES_LANE_RESERVED_IN_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_serdes_REGS_H__ */
/** @} end of ... group */

View File

@ -0,0 +1,875 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes_interface.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_INTERFACE_H__
#define __AL_HAL_SERDES_INTERFACE_H__
#include "al_hal_common.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
enum al_serdes_type {
AL_SRDS_TYPE_HSSP,
AL_SRDS_TYPE_25G,
};
enum al_serdes_reg_page {
/* Relevant to Serdes hssp and 25g */
AL_SRDS_REG_PAGE_0_LANE_0 = 0,
AL_SRDS_REG_PAGE_1_LANE_1,
/* Relevant to Serdes hssp only */
AL_SRDS_REG_PAGE_2_LANE_2,
AL_SRDS_REG_PAGE_3_LANE_3,
/* Relevant to Serdes hssp and 25g */
AL_SRDS_REG_PAGE_4_COMMON,
/* Relevant to Serdes hssp only */
AL_SRDS_REG_PAGE_0123_LANES_0123 = 7,
/* Relevant to Serdes 25g only */
AL_SRDS_REG_PAGE_TOP,
};
/* Relevant to Serdes hssp only */
enum al_serdes_reg_type {
AL_SRDS_REG_TYPE_PMA = 0,
AL_SRDS_REG_TYPE_PCS,
};
enum al_serdes_lane {
AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0,
AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1,
AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2,
AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3,
AL_SRDS_NUM_LANES,
AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123,
};
/** Serdes loopback mode */
enum al_serdes_lb_mode {
/** No loopback */
AL_SRDS_LB_MODE_OFF,
/**
* Transmits the untimed, partial equalized RX signal out the transmit
* IO pins.
* No clock used (untimed)
*/
AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX,
/**
* Loops back the TX serializer output into the CDR.
* CDR recovered bit clock used (without attenuation)
*/
AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX,
/**
* Loops back the TX driver IO signal to the RX IO pins
* CDR recovered bit clock used (only through IO)
*/
AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO,
/**
* Parallel loopback from the PMA receive lane data ports, to the
* transmit lane data ports
* CDR recovered bit clock used
*/
AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX,
/** Loops received data after elastic buffer to transmit path */
AL_SRDS_LB_MODE_PCS_PIPE,
/** Loops TX data (to PMA) to RX path (instead of PMA data) */
AL_SRDS_LB_MODE_PCS_NEAR_END,
/** Loops receive data prior to interface block to transmit path */
AL_SRDS_LB_MODE_PCS_FAR_END,
};
enum al_serdes_clk_freq {
AL_SRDS_CLK_FREQ_NA,
AL_SRDS_CLK_FREQ_100_MHZ,
AL_SRDS_CLK_FREQ_125_MHZ,
AL_SRDS_CLK_FREQ_156_MHZ,
};
enum al_serdes_clk_src {
AL_SRDS_CLK_SRC_LOGIC_0,
AL_SRDS_CLK_SRC_REF_PINS,
AL_SRDS_CLK_SRC_R2L,
AL_SRDS_CLK_SRC_R2L_PLL,
AL_SRDS_CLK_SRC_L2R,
};
/** Serdes BIST pattern */
enum al_serdes_bist_pattern {
AL_SRDS_BIST_PATTERN_USER,
AL_SRDS_BIST_PATTERN_PRBS7,
AL_SRDS_BIST_PATTERN_PRBS23,
AL_SRDS_BIST_PATTERN_PRBS31,
AL_SRDS_BIST_PATTERN_CLK1010,
};
/** SerDes group rate */
enum al_serdes_rate {
AL_SRDS_RATE_1_8,
AL_SRDS_RATE_1_4,
AL_SRDS_RATE_1_2,
AL_SRDS_RATE_FULL,
};
/** SerDes power mode */
enum al_serdes_pm {
AL_SRDS_PM_PD,
AL_SRDS_PM_P2,
AL_SRDS_PM_P1,
AL_SRDS_PM_P0S,
AL_SRDS_PM_P0,
};
/**
* Tx de-emphasis parameters
*/
enum al_serdes_tx_deemph_param {
AL_SERDES_TX_DEEMP_C_ZERO, /*< c(0) */
AL_SERDES_TX_DEEMP_C_PLUS, /*< c(1) */
AL_SERDES_TX_DEEMP_C_MINUS, /*< c(-1) */
};
struct al_serdes_adv_tx_params {
/*
* select the input values location.
* When set to true the values will be taken from the internal registers
* that will be override with the next following parameters.
* When set to false the values will be taken from external pins (the
* other parameters in this case is not needed)
*/
al_bool override;
/*
* Transmit Amplitude control signal. Used to define the full-scale
* maximum swing of the driver.
* 000 - Not Supported
* 001 - 952mVdiff-pkpk
* 010 - 1024mVdiff-pkpk
* 011 - 1094mVdiff-pkpk
* 100 - 1163mVdiff-pkpk
* 101 - 1227mVdiff-pkpk
* 110 - 1283mVdiff-pkpk
* 111 - 1331mVdiff-pkpk
*/
uint8_t amp;
/* Defines the total number of driver units allocated in the driver */
uint8_t total_driver_units;
/* Defines the total number of driver units allocated to the
* first post-cursor (C+1) tap. */
uint8_t c_plus_1;
/* Defines the total number of driver units allocated to the
* second post-cursor (C+2) tap. */
uint8_t c_plus_2;
/* Defines the total number of driver units allocated to the
* first pre-cursor (C-1) tap. */
uint8_t c_minus_1;
/* TX driver Slew Rate control:
* 00 - 31ps
* 01 - 33ps
* 10 - 68ps
* 11 - 170ps
*/
uint8_t slew_rate;
};
struct al_serdes_adv_rx_params {
/*
* select the input values location.
* When set to true the values will be taken from the internal registers
* that will be override with the next following parameters.
* When set to false the values will be taken based in the equalization
* results (the other parameters in this case is not needed)
*/
al_bool override;
/* RX agc high frequency dc gain:
* -3'b000: -3dB
* -3'b001: -2.5dB
* -3'b010: -2dB
* -3'b011: -1.5dB
* -3'b100: -1dB
* -3'b101: -0.5dB
* -3'b110: -0dB
* -3'b111: 0.5dB
*/
uint8_t dcgain;
/* DFE post-shaping tap 3dB frequency
* -3'b000: 684MHz
* -3'b001: 576MHz
* -3'b010: 514MHz
* -3'b011: 435MHz
* -3'b100: 354MHz
* -3'b101: 281MHz
* -3'b110: 199MHz
* -3'b111: 125MHz
*/
uint8_t dfe_3db_freq;
/* DFE post-shaping tap gain
* 0: no pulse shaping tap
* 1: -24mVpeak
* 2: -45mVpeak
* 3: -64mVpeak
* 4: -80mVpeak
* 5: -93mVpeak
* 6: -101mVpeak
* 7: -105mVpeak
*/
uint8_t dfe_gain;
/* DFE first tap gain control
* -4'b0000: +1mVpeak
* -4'b0001: +10mVpeak
* ....
* -4'b0110: +55mVpeak
* -4'b0111: +64mVpeak
* -4'b1000: -1mVpeak
* -4'b1001: -10mVpeak
* ....
* -4'b1110: -55mVpeak
* -4'b1111: -64mVpeak
*/
uint8_t dfe_first_tap_ctrl;
/* DFE second tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +9mVpeak
* ....
* -4'b0110: +46mVpeak
* -4'b0111: +53mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -9mVpeak
* ....
* -4'b1110: -46mVpeak
* -4'b1111: -53mVpeak
*/
uint8_t dfe_secound_tap_ctrl;
/* DFE third tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +7mVpeak
* ....
* -4'b0110: +38mVpeak
* -4'b0111: +44mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -7mVpeak
* ....
* -4'b1110: -38mVpeak
* -4'b1111: -44mVpeak
*/
uint8_t dfe_third_tap_ctrl;
/* DFE fourth tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +6mVpeak
* ....
* -4'b0110: +29mVpeak
* -4'b0111: +33mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -6mVpeak
* ....
* -4'b1110: -29mVpeak
* -4'b1111: -33mVpeak
*/
uint8_t dfe_fourth_tap_ctrl;
/* Low frequency agc gain (att) select
* -3'b000: Disconnected
* -3'b001: -18.5dB
* -3'b010: -12.5dB
* -3'b011: -9dB
* -3'b100: -6.5dB
* -3'b101: -4.5dB
* -3'b110: -2.9dB
* -3'b111: -1.6dB
*/
uint8_t low_freq_agc_gain;
/* Provides a RX Equalizer pre-hint, prior to beginning
* adaptive equalization */
uint8_t precal_code_sel;
/* High frequency agc boost control
* Min d0: Boost ~4dB
* Max d31: Boost ~20dB
*/
uint8_t high_freq_agc_boost;
};
struct al_serdes_25g_adv_rx_params {
/* ATT (PLE Flat-Band Gain) */
uint8_t att;
/* APG (CTLE's Flat-Band Gain) */
uint8_t apg;
/* LFG (Low-Freq Gain) */
uint8_t lfg;
/* HFG (High-Freq Gain) */
uint8_t hfg;
/* MBG (MidBand-Freq-knob Gain) */
uint8_t mbg;
/* MBF (MidBand-Freq-knob Frequency position Gain) */
uint8_t mbf;
/* DFE Tap1 even#0 Value */
int8_t dfe_first_tap_even0_ctrl;
/* DFE Tap1 even#1 Value */
int8_t dfe_first_tap_even1_ctrl;
/* DFE Tap1 odd#0 Value */
int8_t dfe_first_tap_odd0_ctrl;
/* DFE Tap1 odd#1 Value */
int8_t dfe_first_tap_odd1_ctrl;
/* DFE Tap2 Value */
int8_t dfe_second_tap_ctrl;
/* DFE Tap3 Value */
int8_t dfe_third_tap_ctrl;
/* DFE Tap4 Value */
int8_t dfe_fourth_tap_ctrl;
/* DFE Tap5 Value */
int8_t dfe_fifth_tap_ctrl;
};
struct al_serdes_25g_tx_diag_info {
uint8_t regulated_supply;
int8_t dcd_trim;
uint8_t clk_delay;
uint8_t calp_multiplied_by_2;
uint8_t caln_multiplied_by_2;
};
struct al_serdes_25g_rx_diag_info {
int8_t los_offset;
int8_t agc_offset;
int8_t leq_gainstage_offset;
int8_t leq_eq1_offset;
int8_t leq_eq2_offset;
int8_t leq_eq3_offset;
int8_t leq_eq4_offset;
int8_t leq_eq5_offset;
int8_t summer_even_offset;
int8_t summer_odd_offset;
int8_t vscan_even_offset;
int8_t vscan_odd_offset;
int8_t data_slicer_even0_offset;
int8_t data_slicer_even1_offset;
int8_t data_slicer_odd0_offset;
int8_t data_slicer_odd1_offset;
int8_t edge_slicer_even_offset;
int8_t edge_slicer_odd_offset;
int8_t eye_slicer_even_offset;
int8_t eye_slicer_odd_offset;
uint8_t cdr_clk_i;
uint8_t cdr_clk_q;
uint8_t cdr_dll;
uint8_t cdr_vco_dosc;
uint8_t cdr_vco_fr;
uint16_t cdr_dlpf;
uint8_t ple_resistance;
uint8_t rx_term_mode;
uint8_t rx_coupling;
uint8_t rx_term_cal_code;
uint8_t rx_sheet_res_cal_code;
};
/**
* SRIS parameters
*/
struct al_serdes_sris_params {
/* Controls the frequency accuracy threshold (ppm) for lock detection CDR */
uint16_t ppm_drift_count;
/* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */
uint16_t ppm_drift_max;
/* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */
uint16_t synth_ppm_drift_max;
/* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */
uint8_t full_d2r1;
/* Elastic buffer full threshold for PCIE modes: GEN3 */
uint8_t full_pcie_g3;
/* Elastic buffer midpoint threshold.
* Sets the depth of the buffer while in PCIE mode, GEN1/GEN2
*/
uint8_t rd_threshold_d2r1;
/* Elastic buffer midpoint threshold.
* Sets the depth of the buffer while in PCIE mode, GEN3
*/
uint8_t rd_threshold_pcie_g3;
};
/** SerDes PCIe Rate - values are important for proper behavior */
enum al_serdes_pcie_rate {
AL_SRDS_PCIE_RATE_GEN1 = 0,
AL_SRDS_PCIE_RATE_GEN2,
AL_SRDS_PCIE_RATE_GEN3,
};
struct al_serdes_grp_obj {
void __iomem *regs_base;
/**
* get the type of the serdes.
* Must be implemented for all SerDes unit.
*
* @return the serdes type.
*/
enum al_serdes_type (*type_get)(void);
/**
* Reads a SERDES internal register
*
* @param obj The object context
* @param page The SERDES register page within the group
* @param type The SERDES register type (PMA /PCS)
* @param offset The SERDES register offset (0 - 4095)
* @param data The read data
*
* @return 0 if no error found.
*/
int (*reg_read)(struct al_serdes_grp_obj *, enum al_serdes_reg_page,
enum al_serdes_reg_type, uint16_t, uint8_t *);
/**
* Writes a SERDES internal register
*
* @param obj The object context
* @param page The SERDES register page within the group
* @param type The SERDES register type (PMA /PCS)
* @param offset The SERDES register offset (0 - 4095)
* @param data The data to write
*
* @return 0 if no error found.
*/
int (*reg_write)(struct al_serdes_grp_obj *, enum al_serdes_reg_page,
enum al_serdes_reg_type, uint16_t, uint8_t);
/**
* Enable BIST required overrides
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The required speed rate
*/
void (*bist_overrides_enable)(struct al_serdes_grp_obj *, enum al_serdes_rate);
/**
* Disable BIST required overrides
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The required speed rate
*/
void (*bist_overrides_disable)(struct al_serdes_grp_obj *);
/**
* Rx rate change
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The Rx required rate
*/
void (*rx_rate_change)(struct al_serdes_grp_obj *, enum al_serdes_rate);
/**
* SERDES lane Rx rate change software flow enable
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
void (*rx_rate_change_sw_flow_en)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* SERDES lane Rx rate change software flow disable
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
void (*rx_rate_change_sw_flow_dis)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate override check
*
* @param obj The object context
* @param grp The SERDES group
* @param lane The SERDES lane within the group
*
* @returns AL_TRUE if the override is enabled
*/
al_bool (*pcie_rate_override_is_enabled)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate override control
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param en Enable/disable
*/
void (*pcie_rate_override_enable_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
al_bool en);
/**
* PCIe lane rate get
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
enum al_serdes_pcie_rate (*pcie_rate_get)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate set
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param rate The required rate
*/
void (*pcie_rate_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_pcie_rate rate);
/**
* SERDES group power mode control
*
* @param obj The object context
* @param grp The SERDES group
* @param pm The required power mode
*/
void (*group_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_pm);
/**
* SERDES lane power mode control
*
* @param obj The object context
* @param grp The SERDES group
* @param lane The SERDES lane within the group
* @param rx_pm The required RX power mode
* @param tx_pm The required TX power mode
*/
void (*lane_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_pm, enum al_serdes_pm);
/**
* SERDES group PMA hard reset
* Controls Serdes group PMA hard reset
*
* @param obj The object context
* @param grp The SERDES group
* @param enable Enable/disable hard reset
*/
void (*pma_hard_reset_group)(struct al_serdes_grp_obj *, al_bool);
/**
* SERDES lane PMA hard reset
* Controls Serdes lane PMA hard reset
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable/disable hard reset
*/
void (*pma_hard_reset_lane)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* Configure SERDES loopback
* Controls the loopback
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param mode The requested loopback mode
*/
void (*loopback_control)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_lb_mode);
/**
* SERDES BIST pattern selection
* Selects the BIST pattern to be used
*
* @param obj The object context
* @param pattern The pattern to set
* @param user_data The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER)
* 80 bits (8 bytes array)
*/
void (*bist_pattern_select)(struct al_serdes_grp_obj *,
enum al_serdes_bist_pattern, uint8_t *);
/**
* SERDES BIST TX Enable
* Enables/disables TX BIST per lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable or disable TX BIST
*/
void (*bist_tx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* SERDES BIST TX single bit error injection
* Injects single bit error during a TX BIST
*
* @param obj The object context
*/
void (*bist_tx_err_inject)(struct al_serdes_grp_obj *);
/**
* SERDES BIST RX Enable
* Enables/disables RX BIST per lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable or disable TX BIST
*/
void (*bist_rx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* SERDES BIST RX status
* Checks the RX BIST status for a specific SERDES lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param is_locked An indication whether RX BIST is locked
* @param err_cnt_overflow An indication whether error count overflow occured
* @param err_cnt Current bit error count
*/
void (*bist_rx_status)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool *,
al_bool *, uint32_t *);
/**
* Set the tx de-emphasis to preset values
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
*/
void (*tx_deemph_preset)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Increase tx de-emphasis param.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param param which tx de-emphasis to change
*
* @return false in case max is reached. true otherwise.
*/
al_bool (*tx_deemph_inc)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_tx_deemph_param);
/**
* Decrease tx de-emphasis param.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param param which tx de-emphasis to change
*
* @return false in case min is reached. true otherwise.
*/
al_bool (*tx_deemph_dec)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_tx_deemph_param);
/**
* run Rx eye measurement.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param timeout timeout in uSec
* @param value Rx eye measurement value
* (0 - completely closed eye, 0xffff - completely open eye).
*
* @return 0 if no error found.
*/
int (*eye_measure_run)(struct al_serdes_grp_obj *, enum al_serdes_lane,
uint32_t, unsigned int *);
/**
* Eye diagram single sampling
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI)
* @param y Sampling Y position (0 - 62 --> 500mV ... -500mV)
* @param timeout timeout in uSec
* @param value Eye diagram sample value (BER - 0x0000 - 0xffff)
*
* @return 0 if no error found.
*/
int (*eye_diag_sample)(struct al_serdes_grp_obj *, enum al_serdes_lane,
unsigned int, int, unsigned int, unsigned int *);
/**
* Eye diagram full run
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param x_start Sampling from X position
* @param x_stop Sampling to X position
* @param x_step jump in x_step
* @param y_start Sampling from Y position
* @param y_stop Sampling to Y position
* @param y_step jump in y_step
* @param num_bits_per_sample How many bits to check
* @param buf array of results
* @param buf_size array size - must be equal to
* (((y_stop - y_start) / y_step) + 1) *
* (((x_stop - x_start) / x_step) + 1)
*
* @return 0 if no error found.
*/
int (*eye_diag_run)(struct al_serdes_grp_obj *, enum al_serdes_lane,
int, int, unsigned int, int, int, unsigned int, uint64_t, uint64_t *,
uint32_t);
/**
* Check if signal is detected
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if signal is detected. false otherwise.
*/
al_bool (*signal_is_detected)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Check if CDR is locked
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if cdr is locked. false otherwise.
*/
al_bool (*cdr_is_locked)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Check if rx is valid for this lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if rx is valid. false otherwise.
*/
al_bool (*rx_valid)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* configure tx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx parameters
*/
void (*tx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* read tx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx parameters
*/
void (*tx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* configure rx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx parameters
*/
void (*rx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* read rx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx parameters
*/
void (*rx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock
*
* @param obj The object context
*
*/
void (*mode_set_sgmii)(struct al_serdes_grp_obj *);
/**
* Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock
*
* @param obj The object context
*
*/
void (*mode_set_kr)(struct al_serdes_grp_obj *);
/**
* performs SerDes HW equalization test and update equalization parameters
*
* @param obj the object context
* @param lane The SERDES lane within the group
*/
int (*rx_equalization)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* performs Rx equalization and compute the width and height of the eye
*
* @param obj the object context
* @param lane The SERDES lane within the group
* @param width the output width of the eye
* @param height the output height of the eye
*/
int (*calc_eye_size)(struct al_serdes_grp_obj *, enum al_serdes_lane, int *, int *);
/**
* SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking)
* Currently available only for PCIe interfaces.
* When working with local Refclk, same SRIS configuration in both serdes sides
* (EP and RC in PCIe interface) is required.
*
* performs SRIS configuration according to params
*
* @param obj the object context
* @param params the SRIS parameters
*/
void (*sris_config)(struct al_serdes_grp_obj *, void *);
/**
* set SERDES dcgain parameter
*
* @param obj the object context
* @param dcgain dcgain value to set
*/
void (*dcgain_set)(struct al_serdes_grp_obj *, uint8_t);
/**
* read tx diagnostics info
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx diagnostics info structure
*/
void (*tx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*);
/**
* read rx diagnostics info
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx diagnostics info structure
*/
void (*rx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*);
};
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_HAL_SERDES_INTERFACE_H__ */
/** @} end of SERDES group */

View File

@ -70,7 +70,6 @@ extern "C" {
/* Default Max number of descriptors supported per action */
#define AL_UDMA_DEFAULT_MAX_ACTN_DESCS 16
#define AL_UDMA_REV_ID_0 0
#define AL_UDMA_REV_ID_1 1
#define AL_UDMA_REV_ID_2 2
@ -130,8 +129,8 @@ union al_udma_desc {
#define AL_S2M_DESC_LEN2_MASK (0x3fff << AL_S2M_DESC_LEN2_SHIFT)
#define AL_S2M_DESC_LEN2_GRANULARITY_SHIFT 6
/* TX/RX descriptor VMID field (in the buffer address 64 bit field) */
#define AL_UDMA_DESC_VMID_SHIFT 48
/* TX/RX descriptor Target-ID field (in the buffer address 64 bit field) */
#define AL_UDMA_DESC_TGTID_SHIFT 48
/** UDMA completion descriptor */
union al_udma_cdesc {
@ -168,11 +167,11 @@ struct al_block {
uint32_t num; /**< Number of buffers of the block */
/**<
* VMID to be assigned to the block descriptors
* Requires VMID in descriptor to be enabled for the specific UDMA
* Target-ID to be assigned to the block descriptors
* Requires Target-ID in descriptor to be enabled for the specific UDMA
* queue.
*/
uint16_t vmid;
uint16_t tgtid;
};
/** UDMA type */

View File

@ -565,7 +565,7 @@ int al_udma_s2m_pref_set(struct al_udma *udma,
reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
reg |=(conf->min_burst_above_thr <<
UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) &
UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, reg);
@ -1114,260 +1114,105 @@ int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q,
return 0;
}
/* UDMA VMID control configuration */
void al_udma_gen_vmid_conf_set(
/* UDMA Target-ID control configuration per queue */
void al_udma_gen_tgtid_conf_queue_set(
struct unit_regs *unit_regs,
struct al_udma_gen_vmid_conf *conf)
struct al_udma_gen_tgtid_conf *conf,
uint32_t qid)
{
uint32_t *tx_tgtid_reg, *rx_tgtid_reg, *tx_tgtaddr_reg, *rx_tgtaddr_reg;
unsigned int rev_id;
al_reg_write32_masked(
&unit_regs->gen.vmid.cfg_vmid_0,
UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK |
UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK |
UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK |
UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK,
(((conf->tx_q_conf[0].desc_en << 0) |
(conf->tx_q_conf[1].desc_en << 1) |
(conf->tx_q_conf[2].desc_en << 2) |
(conf->tx_q_conf[3].desc_en << 3)) <<
UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT) |
(((conf->tx_q_conf[0].queue_en << 0) |
(conf->tx_q_conf[1].queue_en << 1) |
(conf->tx_q_conf[2].queue_en << 2) |
(conf->tx_q_conf[3].queue_en << 3)) <<
UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT) |
(((conf->rx_q_conf[0].desc_en << 0) |
(conf->rx_q_conf[1].desc_en << 1) |
(conf->rx_q_conf[2].desc_en << 2) |
(conf->rx_q_conf[3].desc_en << 3)) <<
UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT) |
(((conf->rx_q_conf[0].queue_en << 0) |
(conf->rx_q_conf[1].queue_en << 1) |
(conf->rx_q_conf[2].queue_en << 2) |
(conf->rx_q_conf[3].queue_en << 3)) <<
UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT));
/* VMID per queue */
al_reg_write32(
&unit_regs->gen.vmid.cfg_vmid_1,
(conf->tx_q_conf[0].vmid <<
UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT) |
(conf->tx_q_conf[1].vmid <<
UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT));
al_reg_write32(
&unit_regs->gen.vmid.cfg_vmid_2,
(conf->tx_q_conf[2].vmid <<
UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT) |
(conf->tx_q_conf[3].vmid <<
UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT));
al_reg_write32(
&unit_regs->gen.vmid.cfg_vmid_3,
(conf->rx_q_conf[0].vmid <<
UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT) |
(conf->rx_q_conf[1].vmid <<
UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT));
al_reg_write32(
&unit_regs->gen.vmid.cfg_vmid_4,
(conf->rx_q_conf[2].vmid <<
UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT) |
(conf->rx_q_conf[3].vmid <<
UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT));
/* VMADDR per queue */
al_assert(qid < DMA_MAX_Q);
rev_id = al_udma_get_revision(unit_regs);
/* Target-ID TX DESC EN */
al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
(conf->tx_q_conf[qid].desc_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT,
(conf->tx_q_conf[qid].desc_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT);
/* Target-ID TX QUEUE EN */
al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
(conf->tx_q_conf[qid].queue_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT,
(conf->tx_q_conf[qid].queue_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT);
/* Target-ID RX DESC EN */
al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
(conf->rx_q_conf[qid].desc_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT,
(conf->rx_q_conf[qid].desc_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT);
/* Target-ID RX QUEUE EN */
al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
(conf->rx_q_conf[qid].queue_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT,
(conf->rx_q_conf[qid].queue_en << qid) <<
UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT);
switch (qid) {
case 0:
case 1:
tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_1;
rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_3;
tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_0;
rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_2;
break;
case 2:
case 3:
tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_2;
rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_4;
tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_1;
rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_3;
break;
default:
al_assert(AL_FALSE);
return;
}
al_reg_write32_masked(tx_tgtid_reg,
UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
conf->tx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
al_reg_write32_masked(rx_tgtid_reg,
UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
conf->rx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
if (rev_id >= AL_UDMA_REV_ID_REV2) {
al_reg_write32(
&unit_regs->gen.vmaddr.cfg_vmaddr_0,
(conf->tx_q_conf[0].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT) |
(conf->tx_q_conf[1].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT));
al_reg_write32_masked(tx_tgtaddr_reg,
UDMA_GEN_TGTADDR_CFG_MASK(qid),
conf->tx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
al_reg_write32(
&unit_regs->gen.vmaddr.cfg_vmaddr_1,
(conf->tx_q_conf[2].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT) |
(conf->tx_q_conf[3].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT));
al_reg_write32(
&unit_regs->gen.vmaddr.cfg_vmaddr_2,
(conf->rx_q_conf[0].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT) |
(conf->rx_q_conf[1].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT));
al_reg_write32(
&unit_regs->gen.vmaddr.cfg_vmaddr_3,
(conf->rx_q_conf[2].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT) |
(conf->rx_q_conf[3].vmaddr <<
UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT));
al_reg_write32_masked(rx_tgtaddr_reg,
UDMA_GEN_TGTADDR_CFG_MASK(qid),
conf->rx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
}
}
/* UDMA VMID MSIX control configuration */
void al_udma_gen_vmid_msix_conf_set(
/* UDMA Target-ID control configuration */
void al_udma_gen_tgtid_conf_set(
struct unit_regs *unit_regs,
struct al_udma_gen_tgtid_conf *conf)
{
int i;
for (i = 0; i < DMA_MAX_Q; i++)
al_udma_gen_tgtid_conf_queue_set(unit_regs, conf, i);
}
/* UDMA Target-ID MSIX control configuration */
void al_udma_gen_tgtid_msix_conf_set(
struct unit_regs *unit_regs,
struct al_udma_gen_vmid_msix_conf *conf)
struct al_udma_gen_tgtid_msix_conf *conf)
{
al_reg_write32_masked(
&unit_regs->gen.vmid.cfg_vmid_0,
UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN |
UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL,
(conf->access_en ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN : 0) |
(conf->sel ? UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL : 0));
&unit_regs->gen.tgtid.cfg_tgtid_0,
UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN |
UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL,
(conf->access_en ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN : 0) |
(conf->sel ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL : 0));
}
/* UDMA VMID control advanced Tx queue configuration */
void al_udma_gen_vmid_advanced_tx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_tx_q_conf *conf)
{
struct udma_gen_regs *gen_regs = q->udma->gen_regs;
struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid];
al_reg_write32_masked(
&vmpr->cfg_vmpr_0,
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK |
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN,
conf->tx_q_addr_hi_sel |
((conf->tx_q_data_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN : 0) |
((conf->tx_q_prefetch_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN : 0) |
((conf->tx_q_compl_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN : 0));
al_reg_write32(
&vmpr->cfg_vmpr_1,
conf->tx_q_addr_hi);
al_reg_write32_masked(
&vmpr->cfg_vmpr_2,
UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK,
(conf->tx_q_prefetch_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT) |
(conf->tx_q_compl_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT));
al_reg_write32_masked(
&vmpr->cfg_vmpr_3,
UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK,
(conf->tx_q_data_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT) |
(conf->tx_q_data_vmid_mask <<
UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT));
}
/** UDMA VMID control advanced Rx queue configuration */
void al_udma_gen_vmid_advanced_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_rx_q_conf *conf)
{
struct udma_gen_regs *gen_regs = q->udma->gen_regs;
struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid];
al_reg_write32_masked(
&vmpr->cfg_vmpr_4,
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN |
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN,
(conf->rx_q_addr_hi_sel <<
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT) |
((conf->rx_q_data_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN : 0) |
(conf->rx_q_data_buff2_addr_hi_sel <<
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT) |
((conf->rx_q_data_buff2_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN : 0) |
(conf->rx_q_ddp_addr_hi_sel <<
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT) |
((conf->rx_q_ddp_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN : 0) |
((conf->rx_q_prefetch_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN : 0) |
((conf->rx_q_compl_vmid_en == AL_TRUE) ?
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN : 0));
al_reg_write32_masked(
&vmpr->cfg_vmpr_6,
UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK,
(conf->rx_q_prefetch_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT) |
(conf->rx_q_compl_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT));
al_reg_write32_masked(
&vmpr->cfg_vmpr_7,
UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK,
(conf->rx_q_data_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT) |
(conf->rx_q_data_vmid_mask <<
UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT));
al_reg_write32_masked(
&vmpr->cfg_vmpr_8,
UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK,
(conf->rx_q_data_buff2_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT) |
(conf->rx_q_data_buff2_mask <<
UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT));
al_reg_write32_masked(
&vmpr->cfg_vmpr_9,
UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK |
UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK,
(conf->rx_q_ddp_vmid <<
UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT) |
(conf->rx_q_ddp_mask <<
UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT));
al_reg_write32(
&vmpr->cfg_vmpr_10,
conf->rx_q_addr_hi);
al_reg_write32(
&vmpr->cfg_vmpr_11,
conf->rx_q_data_buff2_addr_hi);
al_reg_write32(
&vmpr->cfg_vmpr_12,
conf->rx_q_ddp_addr_hi);
}
/* UDMA header split buffer 2 Rx queue configuration */
void al_udma_gen_hdr_split_buff2_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_hdr_split_buff2_q_conf *conf)
{
struct udma_gen_regs *gen_regs = q->udma->gen_regs;
struct udma_gen_vmpr *vmpr = &gen_regs->vmpr[q->qid];
al_reg_write32_masked(
&vmpr->cfg_vmpr_4,
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK,
conf->add_msb_sel <<
UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT);
al_reg_write32(
&vmpr->cfg_vmpr_5,
conf->addr_msb);
}

View File

@ -1,5 +1,4 @@
/*-
*******************************************************************************
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
@ -313,237 +312,40 @@ struct al_udma_s2m_q_comp_conf {
uint8_t q_qos; /* queue QoS */
};
/** UDMA per queue VMID control configuration */
struct al_udma_gen_vmid_q_conf {
/* Enable usage of the VMID per queue according to 'vmid' */
/** UDMA per queue Target-ID control configuration */
struct al_udma_gen_tgtid_q_conf {
/* Enable usage of the Target-ID per queue according to 'tgtid' */
al_bool queue_en;
/* Enable usage of the VMID from the descriptor buffer address 63:48 */
/* Enable usage of the Target-ID from the descriptor buffer address 63:48 */
al_bool desc_en;
/* VMID to be applied when 'queue_en' is asserted */
uint16_t vmid;
/* Target-ID to be applied when 'queue_en' is asserted */
uint16_t tgtid;
/* VMADDR to be applied to msbs when 'desc_en' is asserted.
/* TGTADDR to be applied to msbs when 'desc_en' is asserted.
* Relevant for revisions >= AL_UDMA_REV_ID_REV2 */
uint16_t vmaddr;
uint16_t tgtaddr;
};
/** UDMA VMID control configuration */
struct al_udma_gen_vmid_conf {
/** UDMA Target-ID control configuration */
struct al_udma_gen_tgtid_conf {
/* TX queue configuration */
struct al_udma_gen_vmid_q_conf tx_q_conf[DMA_MAX_Q];
struct al_udma_gen_tgtid_q_conf tx_q_conf[DMA_MAX_Q];
/* RX queue configuration */
struct al_udma_gen_vmid_q_conf rx_q_conf[DMA_MAX_Q];
struct al_udma_gen_tgtid_q_conf rx_q_conf[DMA_MAX_Q];
};
/** UDMA VMID MSIX control configuration */
struct al_udma_gen_vmid_msix_conf {
/* Enable write to all VMID_n registers in the MSI-X Controller */
/** UDMA Target-ID MSIX control configuration */
struct al_udma_gen_tgtid_msix_conf {
/* Enable write to all TGTID_n registers in the MSI-X Controller */
al_bool access_en;
/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */
/* use TGTID_n [7:0] from MSI-X Controller for MSI-X message */
al_bool sel;
};
/** UDMA per Tx queue advanced VMID control configuration */
struct al_udma_gen_vmid_advanced_tx_q_conf {
/**********************************************************************
* Tx Data VMID
**********************************************************************/
/* Tx data VMID enable */
al_bool tx_q_data_vmid_en;
/*
* For Tx data reads, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'tx_q_addr_hi_sel'
*/
unsigned int tx_q_addr_hi;
/*
* For Tx data reads, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
* When 'tx_q_addr_hi_sel'=32 all of 'tx_q_addr_hi' will be taken.
* When 'tx_q_addr_hi_sel'=0 none of it will be taken, and when any
* value in between, it will start from the MSB bit and sweep down as
* many bits as needed. For example if 'tx_q_addr_hi_sel'=8, the final
* address [63:56] will carry 'tx_q_addr_hi'[31:24] while [55:32] will
* carry the original buffer address[55:32].
*/
unsigned int tx_q_addr_hi_sel;
/*
* Tx data read VMID
* Masked per bit with 'tx_q_data_vmid_mask'
*/
unsigned int tx_q_data_vmid;
/*
* Tx data read VMID mask
* Each '1' selects from the buffer address, each '0' selects from
* 'tx_q_data_vmid'
*/
unsigned int tx_q_data_vmid_mask;
/**********************************************************************
* Tx prefetch VMID
**********************************************************************/
/* Tx prefetch VMID enable */
al_bool tx_q_prefetch_vmid_en;
/* Tx prefetch VMID */
unsigned int tx_q_prefetch_vmid;
/**********************************************************************
* Tx completion VMID
**********************************************************************/
/* Tx completion VMID enable */
al_bool tx_q_compl_vmid_en;
/* Tx completion VMID */
unsigned int tx_q_compl_vmid;
};
/** UDMA per Rx queue advanced VMID control configuration */
struct al_udma_gen_vmid_advanced_rx_q_conf {
/**********************************************************************
* Rx Data VMID
**********************************************************************/
/* Rx data VMID enable */
al_bool rx_q_data_vmid_en;
/*
* For Rx data writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_addr_hi_sel'
*/
unsigned int rx_q_addr_hi;
/*
* For Rx data writes, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
*/
unsigned int rx_q_addr_hi_sel;
/*
* Rx data write VMID
* Masked per bit with 'rx_q_data_vmid_mask'
*/
unsigned int rx_q_data_vmid;
/* Rx data write VMID mask */
unsigned int rx_q_data_vmid_mask;
/**********************************************************************
* Rx Data Buffer 2 VMID
**********************************************************************/
/* Rx data buff2 VMID enable */
al_bool rx_q_data_buff2_vmid_en;
/*
* For Rx data buff2 writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_data_buff2_addr_hi_sel'
*/
unsigned int rx_q_data_buff2_addr_hi;
/*
* For Rx data buff2 writes, 6 bits serving the number of bits taken
* from the extra register on account of bits coming from the original
* address field.
*/
unsigned int rx_q_data_buff2_addr_hi_sel;
/*
* Rx data buff2 write VMID
* Masked per bit with 'rx_q_data_buff2_mask'
*/
unsigned int rx_q_data_buff2_vmid;
/* Rx data buff2 write VMID mask */
unsigned int rx_q_data_buff2_mask;
/**********************************************************************
* Rx DDP VMID
**********************************************************************/
/* Rx DDP write VMID enable */
al_bool rx_q_ddp_vmid_en;
/*
* For Rx DDP writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_ddp_addr_hi_sel'
*/
unsigned int rx_q_ddp_addr_hi;
/*
* For Rx DDP writes, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
*/
unsigned int rx_q_ddp_addr_hi_sel;
/*
* Rx DDP write VMID
* Masked per bit with 'rx_q_ddp_mask'
*/
unsigned int rx_q_ddp_vmid;
/* Rx DDP write VMID mask */
unsigned int rx_q_ddp_mask;
/**********************************************************************
* Rx prefetch VMID
**********************************************************************/
/* Rx prefetch VMID enable */
al_bool rx_q_prefetch_vmid_en;
/* Rx prefetch VMID */
unsigned int rx_q_prefetch_vmid;
/**********************************************************************
* Rx completion VMID
**********************************************************************/
/* Rx completion VMID enable */
al_bool rx_q_compl_vmid_en;
/* Rx completion VMID */
unsigned int rx_q_compl_vmid;
};
/**
* Header split, buffer 2 per queue configuration
* When header split is enabled, Buffer_2 is used as an address for the header
* data. Buffer_2 is defined as 32-bits in the RX descriptor and it is defined
* that the MSB ([63:32]) of Buffer_1 is used as address [63:32] for the header
* address.
*/
struct al_udma_gen_hdr_split_buff2_q_conf {
/*
* MSB of the 64-bit address (bits [63:32]) that can be used for header
* split for this queue
*/
unsigned int addr_msb;
/*
* Determine how to select the MSB (bits [63:32]) of the address when
* header split is enabled (4 bits, one per byte)
* - Bits [3:0]:
* [0] selector for bits [39:32]
* [1] selector for bits [47:40]
* [2] selector for bits [55:48]
* [3] selector for bits [63:55]
* - Bit value:
* 0 Use Buffer_1 (legacy operation)
* 1 Use the queue configuration 'addr_msb'
*/
unsigned int add_msb_sel;
};
/* Report Error - to be used for abort */
void al_udma_err_report(struct al_udma *udma);
@ -721,30 +523,21 @@ int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q,
int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q,
struct al_udma_s2m_q_comp_conf *conf);
/** UDMA VMID control configuration */
void al_udma_gen_vmid_conf_set(
/** UDMA Target-ID control configuration per queue */
void al_udma_gen_tgtid_conf_queue_set(
struct unit_regs *unit_regs,
struct al_udma_gen_tgtid_conf *conf,
uint32_t qid);
/** UDMA Target-ID control configuration */
void al_udma_gen_tgtid_conf_set(
struct unit_regs __iomem *unit_regs,
struct al_udma_gen_vmid_conf *conf);
struct al_udma_gen_tgtid_conf *conf);
/** UDMA VMID MSIX control configuration */
void al_udma_gen_vmid_msix_conf_set(
/** UDMA Target-ID MSIX control configuration */
void al_udma_gen_tgtid_msix_conf_set(
struct unit_regs __iomem *unit_regs,
struct al_udma_gen_vmid_msix_conf *conf);
/** UDMA VMID control advanced Tx queue configuration */
void al_udma_gen_vmid_advanced_tx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_tx_q_conf *conf);
/** UDMA VMID control advanced Rx queue configuration */
void al_udma_gen_vmid_advanced_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_rx_q_conf *conf);
/** UDMA header split buffer 2 Rx queue configuration */
void al_udma_gen_hdr_split_buff2_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_hdr_split_buff2_q_conf *conf);
struct al_udma_gen_tgtid_msix_conf *conf);
/* *INDENT-OFF* */
#ifdef __cplusplus

View File

@ -425,9 +425,9 @@ void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid)
al_dbg(" comp_head_ptr = %p\n", queue->comp_head_ptr);
al_dbg(" pkt_crnt_descs = %d\n", (uint32_t)queue->pkt_crnt_descs);
al_dbg(" comp_ring_id = %d\n", (uint32_t)queue->comp_ring_id);
al_dbg(" desc_phy_base = 0x%016llx\n", (uint64_t)queue->desc_phy_base);
al_dbg(" cdesc_phy_base = 0x%016llx\n",
(uint64_t)queue->cdesc_phy_base);
al_dbg(" desc_phy_base = 0x%016jx\n", (uintmax_t)queue->desc_phy_base);
al_dbg(" cdesc_phy_base = 0x%016jx\n",
(uintmax_t)queue->cdesc_phy_base);
al_dbg(" flags = 0x%08x\n", (uint32_t)queue->flags);
al_dbg(" size = %d\n", (uint32_t)queue->size);
al_dbg(" status = %d\n", (uint32_t)queue->status);
@ -471,7 +471,7 @@ void al_udma_ring_print(struct al_udma *udma, uint32_t qid,
}
for (i = 0; i < queue->size; i++) {
uint32_t *curr_addr = (void*)((uint32_t)base_ptr + i * desc_size);
uint32_t *curr_addr = (void*)((uintptr_t)base_ptr + i * desc_size);
if (desc_size == 16)
al_dbg("[%04d](%p): %08x %08x %08x %08x\n",
i,

View File

@ -610,5 +610,23 @@ static INLINE uint32_t al_udma_iofic_read_cause(
return al_iofic_read_cause(al_udma_iofic_reg_base_get(regs, level), group);
}
/**
* clear bits in the interrupt cause register for a given group
*
* @param regs pointer to udma unit registers
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
* @param mask bitwise of bits to be cleared, set bits will be cleared.
*/
static INLINE void al_udma_iofic_clear_cause(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group,
uint32_t mask)
{
al_assert(al_udma_iofic_level_and_group_valid(level, group));
al_iofic_clear_cause(al_udma_iofic_reg_base_get(regs, level), group, mask);
}
#endif
/** @} end of UDMA group */

View File

@ -70,7 +70,6 @@ const char *const al_udma_states_name[] = {
static void al_udma_set_defaults(struct al_udma *udma)
{
uint32_t tmp;
uint8_t rev_id = udma->rev_id;
if (udma->type == UDMA_TX) {
@ -85,25 +84,11 @@ static void al_udma_set_defaults(struct al_udma *udma)
256 << UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_SHIFT);
}
if (rev_id == AL_UDMA_REV_ID_0)
/* disable AXI timeout for M0*/
al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 0);
else
/* set AXI timeout to 1M (~2.6 ms) */
al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000);
/* set AXI timeout to 1M (~2.6 ms) */
al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000);
al_reg_write32(&tmp_unit_regs->m2s.m2s_comp.cfg_application_ack
, 0); /* Ack time out */
if (rev_id == AL_UDMA_REV_ID_0) {
tmp = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
tmp &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
tmp |= 4 << UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT;
al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1
, tmp);
}
}
if (udma->type == UDMA_RX) {
al_reg_write32(
@ -365,14 +350,13 @@ int al_udma_q_init(struct al_udma *udma, uint32_t qid,
al_udma_q_enable(udma_q, 1);
al_dbg("udma [%s %d]: %s q init. size 0x%x\n"
" desc ring info: phys base 0x%llx virt base %p\n"
" cdesc ring info: phys base 0x%llx virt base %p "
"entry size 0x%x",
" desc ring info: phys base 0x%llx virt base %p)",
udma_q->udma->name, udma_q->qid,
udma->type == UDMA_TX ? "Tx" : "Rx",
q_params->size,
(unsigned long long)q_params->desc_phy_base,
q_params->desc_base,
q_params->desc_base);
al_dbg(" cdesc ring info: phys base 0x%llx virt base %p entry size 0x%x",
(unsigned long long)q_params->cdesc_phy_base,
q_params->cdesc_base,
q_params->cdesc_size);

View File

@ -1,5 +1,4 @@
/*-
*******************************************************************************
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
@ -97,48 +96,48 @@ struct udma_gen_sram_ctrl {
/* [0x0] Timing configuration */
uint32_t timing;
};
struct udma_gen_vmid {
/* [0x0] VMID control */
uint32_t cfg_vmid_0;
/* [0x4] TX queue 0/1 VMID */
uint32_t cfg_vmid_1;
/* [0x8] TX queue 2/3 VMID */
uint32_t cfg_vmid_2;
/* [0xc] RX queue 0/1 VMID */
uint32_t cfg_vmid_3;
/* [0x10] RX queue 2/3 VMID */
uint32_t cfg_vmid_4;
struct udma_gen_tgtid {
/* [0x0] Target-ID control */
uint32_t cfg_tgtid_0;
/* [0x4] TX queue 0/1 Target-ID */
uint32_t cfg_tgtid_1;
/* [0x8] TX queue 2/3 Target-ID */
uint32_t cfg_tgtid_2;
/* [0xc] RX queue 0/1 Target-ID */
uint32_t cfg_tgtid_3;
/* [0x10] RX queue 2/3 Target-ID */
uint32_t cfg_tgtid_4;
};
struct udma_gen_vmaddr {
/* [0x0] TX queue 0/1 VMADDR */
uint32_t cfg_vmaddr_0;
/* [0x4] TX queue 2/3 VMADDR */
uint32_t cfg_vmaddr_1;
/* [0x8] RX queue 0/1 VMADDR */
uint32_t cfg_vmaddr_2;
/* [0xc] RX queue 2/3 VMADDR */
uint32_t cfg_vmaddr_3;
struct udma_gen_tgtaddr {
/* [0x0] TX queue 0/1 Target-Address */
uint32_t cfg_tgtaddr_0;
/* [0x4] TX queue 2/3 Target-Address */
uint32_t cfg_tgtaddr_1;
/* [0x8] RX queue 0/1 Target-Address */
uint32_t cfg_tgtaddr_2;
/* [0xc] RX queue 2/3 Target-Address */
uint32_t cfg_tgtaddr_3;
};
struct udma_gen_vmpr {
/* [0x0] TX VMPR control */
uint32_t cfg_vmpr_0;
/* [0x4] TX VMPR Address High Regsiter */
uint32_t cfg_vmpr_1;
/* [0x8] TX queue VMID values */
/* [0x8] TX queue Target-ID values */
uint32_t cfg_vmpr_2;
/* [0xc] TX queue VMID values */
/* [0xc] TX queue Target-ID values */
uint32_t cfg_vmpr_3;
/* [0x10] RX VMPR control */
uint32_t cfg_vmpr_4;
/* [0x14] RX VMPR Buffer2 MSB address */
uint32_t cfg_vmpr_5;
/* [0x18] RX queue VMID values */
/* [0x18] RX queue Target-ID values */
uint32_t cfg_vmpr_6;
/* [0x1c] RX queue BUF1 VMID values */
/* [0x1c] RX queue BUF1 Target-ID values */
uint32_t cfg_vmpr_7;
/* [0x20] RX queue BUF2 VMID values */
/* [0x20] RX queue BUF2 Target-ID values */
uint32_t cfg_vmpr_8;
/* [0x24] RX queue Direct Data Placement VMID values */
/* [0x24] RX queue Direct Data Placement Target-ID values */
uint32_t cfg_vmpr_9;
/* [0x28] RX VMPR BUF1 Address High Regsiter */
uint32_t cfg_vmpr_10;
@ -156,8 +155,8 @@ struct udma_gen_regs {
struct udma_gen_axi axi; /* [0x2280] */
struct udma_gen_sram_ctrl sram_ctrl[25]; /* [0x2380] */
uint32_t rsrvd_1[2];
struct udma_gen_vmid vmid; /* [0x23ec] */
struct udma_gen_vmaddr vmaddr; /* [0x2400] */
struct udma_gen_tgtid tgtid; /* [0x23ec] */
struct udma_gen_tgtaddr tgtaddr; /* [0x2400] */
uint32_t rsrvd_2[252];
struct udma_gen_vmpr vmpr[4]; /* [0x2800] */
};
@ -236,176 +235,182 @@ struct udma_gen_regs {
/* Read margin enable */
#define UDMA_GEN_SRAM_CTRL_TIMING_RMEB (1 << 24)
/**** cfg_vmid_0 register ****/
/* For M2S queues 3:0, enable usage of the VMID from the buffer address 63:56 */
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK 0x0000000F
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT 0
/**** cfg_tgtid_0 register ****/
/* For M2S queues 3:0, enable usage of the Target-ID from the buffer address 63:56 */
#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_MASK 0x0000000F
#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT 0
/*
* For M2S queues 3:0, enable usage of the VMID from the configuration register
* (cfg_vmid_1/2 used for M2S queue_x)
* For M2S queues 3:0, enable usage of the Target-ID from the configuration register
* (cfg_tgtid_1/2 used for M2S queue_x)
*/
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK 0x000000F0
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT 4
/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */
#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL (1 << 8)
/* Enable write to all VMID_n registers in the MSI-X Controller */
#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN (1 << 9)
/* For S2M queues 3:0, enable usage of the VMID from the buffer address 63:56 */
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK 0x000F0000
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT 16
#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_MASK 0x000000F0
#define UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT 4
/* use Target-ID_n [7:0] from MSI-X Controller for MSI-X message */
#define UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL (1 << 8)
/* Enable write to all Target-ID_n registers in the MSI-X Controller */
#define UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN (1 << 9)
/* For S2M queues 3:0, enable usage of the Target-ID from the buffer address 63:56 */
#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_MASK 0x000F0000
#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT 16
/*
* For S2M queues 3:0, enable usage of the VMID from the configuration register
* (cfg_vmid_3/4 used for M2S queue_x)
* For S2M queues 3:0, enable usage of the Target-ID from the configuration register
* (cfg_tgtid_3/4 used for M2S queue_x)
*/
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK 0x00F00000
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT 20
#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_MASK 0x00F00000
#define UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT 20
/**** cfg_vmid_1 register ****/
/* TX queue 0 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT 0
/* TX queue 1 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT 16
#define UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid) (((qid) & 0x1) ? 16 : 0)
#define UDMA_GEN_TGTID_CFG_TGTID_MASK(qid) (((qid) & 0x1) ? 0xFFFF0000 : 0x0000FFFF)
/**** cfg_vmid_2 register ****/
/* TX queue 2 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT 0
/* TX queue 3 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT 16
/**** cfg_tgtid_1 register ****/
/* TX queue 0 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_0_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_0_TGTID_SHIFT 0
/* TX queue 1 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_1_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_TGTID_CFG_TGTID_1_TX_Q_1_TGTID_SHIFT 16
/**** cfg_vmid_3 register ****/
/* RX queue 0 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT 0
/* RX queue 1 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT 16
/**** cfg_tgtid_2 register ****/
/* TX queue 2 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_2_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_2_TGTID_SHIFT 0
/* TX queue 3 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_3_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_TGTID_CFG_TGTID_2_TX_Q_3_TGTID_SHIFT 16
/**** cfg_vmid_4 register ****/
/* RX queue 2 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT 0
/* RX queue 3 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT 16
/**** cfg_tgtid_3 register ****/
/* RX queue 0 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_0_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_0_TGTID_SHIFT 0
/* RX queue 1 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_1_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_TGTID_CFG_TGTID_3_RX_Q_1_TGTID_SHIFT 16
/**** cfg_vmaddr_0 register ****/
/* TX queue 0 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT 0
/* TX queue 1 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT 16
/**** cfg_tgtid_4 register ****/
/* RX queue 2 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_2_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_2_TGTID_SHIFT 0
/* RX queue 3 Target-ID value */
#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_3_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_TGTID_CFG_TGTID_4_RX_Q_3_TGTID_SHIFT 16
/**** cfg_vmaddr_1 register ****/
/* TX queue 2 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT 0
/* TX queue 3 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT 16
#define UDMA_GEN_TGTADDR_CFG_SHIFT(qid) (((qid) & 0x1) ? 16 : 0)
#define UDMA_GEN_TGTADDR_CFG_MASK(qid) (((qid) & 0x1) ? 0xFFFF0000 : 0x0000FFFF)
/**** cfg_vmaddr_2 register ****/
/* RX queue 0 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT 0
/* RX queue 1 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT 16
/**** cfg_tgtaddr_0 register ****/
/* TX queue 0 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_0_TGTADDR_MASK 0x0000FFFF
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_0_TGTADDR_SHIFT 0
/* TX queue 1 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_1_TGTADDR_MASK 0xFFFF0000
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_0_TX_Q_1_TGTADDR_SHIFT 16
/**** cfg_vmaddr_3 register ****/
/* RX queue 2 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT 0
/* RX queue 3 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT 16
/**** cfg_tgtaddr_1 register ****/
/* TX queue 2 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_2_TGTADDR_MASK 0x0000FFFF
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_2_TGTADDR_SHIFT 0
/* TX queue 3 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_3_TGTADDR_MASK 0xFFFF0000
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_1_TX_Q_3_TGTADDR_SHIFT 16
/**** cfg_tgtaddr_2 register ****/
/* RX queue 0 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_0_TGTADDR_MASK 0x0000FFFF
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_0_TGTADDR_SHIFT 0
/* RX queue 1 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_1_TGTADDR_MASK 0xFFFF0000
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_2_RX_Q_1_TGTADDR_SHIFT 16
/**** cfg_tgtaddr_3 register ****/
/* RX queue 2 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_2_TGTADDR_MASK 0x0000FFFF
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_2_TGTADDR_SHIFT 0
/* RX queue 3 Target-Address value */
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_3_TGTADDR_MASK 0xFFFF0000
#define UDMA_GEN_TGTADDR_CFG_TGTADDR_3_RX_Q_3_TGTADDR_SHIFT 16
/**** cfg_vmpr_0 register ****/
/* TX High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK 0x0000003F
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_SHIFT 0
/* TX Data VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN (1 << 7)
/* TX Prefetch VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN (1 << 28)
/* TX Completions VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN (1 << 29)
/* TX Data Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_TGTID_EN (1 << 7)
/* TX Prefetch Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_TGTID_EN (1 << 28)
/* TX Completions Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_TGTID_EN (1 << 29)
/**** cfg_vmpr_2 register ****/
/* TX queue Prefetch VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT 0
/* TX queue Completion VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT 16
/* TX queue Prefetch Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_TGTID_SHIFT 0
/* TX queue Completion Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_TGTID_SHIFT 16
/**** cfg_vmpr_3 register ****/
/* TX queue Data VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT 0
/* TX queue Data VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT 16
/* TX queue Data Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SHIFT 0
/* TX queue Data Target-ID select */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_TGTID_SEL_SHIFT 16
/**** cfg_vmpr_4 register ****/
/* RX Data Buffer1 - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK 0x0000003F
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT 0
/* RX Data Buffer1 VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN (1 << 7)
/* RX Data Buffer1 Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_TGTID_EN (1 << 7)
/* RX Data Buffer2 - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK 0x00003F00
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT 8
/* RX Data Buffer2 VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN (1 << 15)
/* RX Data Buffer2 Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_TGTID_EN (1 << 15)
/* RX Direct Data Placement - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK 0x003F0000
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT 16
/* RX Direct Data Placement VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN (1 << 23)
/* RX Direct Data Placement Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_TGTID_EN (1 << 23)
/* RX Buffer 2 MSB address word selects per bytes, per queue */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK 0x0F000000
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT 24
/* RX Prefetch VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN (1 << 28)
/* RX Completions VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN (1 << 29)
/* RX Prefetch Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_TGTID_EN (1 << 28)
/* RX Completions Target-ID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_TGTID_EN (1 << 29)
/**** cfg_vmpr_6 register ****/
/* RX queue Prefetch VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT 0
/* RX queue Completion VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT 16
/* RX queue Prefetch Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_TGTID_SHIFT 0
/* RX queue Completion Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_TGTID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_TGTID_SHIFT 16
/**** cfg_vmpr_7 register ****/
/* RX queue Data Buffer 1 VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT 0
/* RX queue Data Buffer 1 VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT 16
/* RX queue Data Buffer 1 Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SHIFT 0
/* RX queue Data Buffer 1 Target-ID select */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_TGTID_SEL_SHIFT 16
/**** cfg_vmpr_8 register ****/
/* RX queue Data Buffer 2 VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT 0
/* RX queue Data Buffer 2 VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT 16
/* RX queue Data Buffer 2 Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SHIFT 0
/* RX queue Data Buffer 2 Target-ID select */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_TGTID_SEL_SHIFT 16
/**** cfg_vmpr_9 register ****/
/* RX queue DDP VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT 0
/* RX queue DDP VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT 16
/* RX queue DDP Target-ID */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SHIFT 0
/* RX queue DDP Target-ID select */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_TGTID_SEL_SHIFT 16
#ifdef __cplusplus
}

View File

@ -274,11 +274,11 @@ extern "C" {
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16)
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16
/* Central VMID enabler. If set, then each entry will be used as programmed */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0)
/* Allow access to store VMID values per entry */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1)
/* VMID Address select */
/* Central Target-ID enabler. If set, then each entry will be used as programmed */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_TGTID_SEL AL_BIT(0)
/* Allow access to store Target-ID values per entry */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_TGTID_ACCESS_EN AL_BIT(1)
/* Target-ID Address select */
/* Tx */
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8)
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8
@ -294,13 +294,13 @@ extern "C" {
/*
* ROB registers
*/
/* Read ROB_Enable, when disabled the read ROB is bypassed */
/* Read ROB Enable, when disabled the read ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0)
/* Read force in-order of every read transaction */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1)
/* Read software reset */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15)
/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */
/* Write ROB Enable, when disabled the Write ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16)
/* Write force in-order of every write transaction */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17)

View File

@ -0,0 +1,59 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include "al_serdes.h"
#include "al_hal_serdes_hssp.h"
#include "al_hal_serdes_25g.h"
static int(*handle_init[AL_SRDS_NUM_GROUPS])(void __iomem *, struct al_serdes_grp_obj *) = {
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
#if CHECK_ALPINE_V2
al_serdes_25g_handle_init,
#endif
};
int al_serdes_handle_grp_init(
void __iomem *serdes_regs_base,
enum al_serdes_group grp,
struct al_serdes_grp_obj *obj)
{
handle_init[grp](serdes_regs_base, obj);
return 0;
}

View File

@ -0,0 +1,78 @@
/*******************************************************************************
Copyright (C) 2013 Annapurna Labs Ltd.
This file is licensed under the terms of the Annapurna Labs' Commercial License
Agreement distributed with the file or available on the software download site.
Recipient shall use the content of this file only on semiconductor devices or
systems developed by or for Annapurna Labs.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_init SerDes Initialization
* @ingroup group_serdes SerDes
* @{
*
* @file al_serdes.h
*
*/
#ifndef __AL_SERDES_H__
#define __AL_SERDES_H__
#include "al_hal_serdes_interface.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#ifdef AL_DEV_ID
#define CHECK_ALPINE_V1 (AL_DEV_ID == AL_DEV_ID_ALPINE_V1)
#define CHECK_ALPINE_V2 (AL_DEV_ID == AL_DEV_ID_ALPINE_V2)
#else
#define CHECK_ALPINE_V1 1
#define CHECK_ALPINE_V2 1
#endif
enum al_serdes_group {
AL_SRDS_GRP_A = 0,
AL_SRDS_GRP_B,
AL_SRDS_GRP_C,
AL_SRDS_GRP_D,
AL_SRDS_NUM_HSSP_GROUPS,
#if CHECK_ALPINE_V2
AL_SRDS_GRP_E = AL_SRDS_NUM_HSSP_GROUPS,
AL_SRDS_NUM_GROUPS,
#else
AL_SRDS_NUM_GROUPS = AL_SRDS_NUM_HSSP_GROUPS,
#endif
};
int al_serdes_handle_grp_init(
void __iomem *serdes_regs_base,
enum al_serdes_group grp,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif
/** @} end of SERDES group */

View File

@ -0,0 +1,70 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* Includes all common header files used by HAL
* @{
* @file al_hal_common.h
*
*/
#ifndef __AL_HAL_COMMON_H__
#define __AL_HAL_COMMON_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
#include "al_hal_types.h"
#include "al_hal_reg_utils.h"
/* Get the maximal value out of two typed values */
#define al_max_t(type, x, y) ({ \
type __max1 = (x); \
type __max2 = (y); \
__max1 > __max2 ? __max1 : __max2; })
/* Get the minimal value out of two typed values */
#define al_min_t(type, x, y) ({ \
type __min1 = (x); \
type __min2 = (y); \
__min1 < __min2 ? __min1 : __min2; })
/* Get the number of elements in an array */
#define AL_ARR_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/** @} end of Common group */
#endif /* __AL_HAL_COMMON_H__ */

View File

@ -68,7 +68,7 @@ extern "C" {
#ifndef AL_ETH_EX
#define AL_ETH_PKT_MAX_BUFS 19
#else
#define AL_ETH_PKT_MAX_BUFS 29
#define AL_ETH_PKT_MAX_BUFS 30
#endif
#endif
@ -136,7 +136,8 @@ enum al_eth_mac_mode {
AL_ETH_MAC_MODE_10G_SGMII, /**< SGMII using the 10G MAC, don't use*/
AL_ETH_MAC_MODE_XLG_LL_40G, /**< applies to 40G mode using the 40G low latency (LL) MAC */
AL_ETH_MAC_MODE_KR_LL_25G, /**< applies to 25G mode using the 10/25G low latency (LL) MAC */
AL_ETH_MAC_MODE_XLG_LL_50G /**< applies to 50G mode using the 40/50G low latency (LL) MAC */
AL_ETH_MAC_MODE_XLG_LL_50G, /**< applies to 50G mode using the 40/50G low latency (LL) MAC */
AL_ETH_MAC_MODE_XLG_LL_25G /**< applies to 25G mode using the 40/50G low latency (LL) MAC */
};
struct al_eth_capabilities {
@ -338,11 +339,11 @@ struct al_eth_meta_data{
/* Packet Rx flags when adding buffer to receive queue */
/**<
* VMID to be assigned to the packet descriptors
* Requires VMID in descriptor to be enabled for the specific UDMA
* Target-ID to be assigned to the packet descriptors
* Requires Target-ID in descriptor to be enabled for the specific UDMA
* queue.
*/
#define AL_ETH_RX_FLAGS_VMID_MASK AL_FIELD_MASK(15, 0)
#define AL_ETH_RX_FLAGS_TGTID_MASK AL_FIELD_MASK(15, 0)
#define AL_ETH_RX_FLAGS_NO_SNOOP AL_M2S_DESC_NO_SNOOP_H
#define AL_ETH_RX_FLAGS_INT AL_M2S_DESC_INT_EN
#define AL_ETH_RX_FLAGS_DUAL_BUF AL_BIT(31)
@ -382,11 +383,11 @@ struct al_eth_pkt{
enum AL_ETH_PROTO_ID outer_l3_proto_idx; /**< for tunneling mode */
/**<
* VMID to be assigned to the packet descriptors
* Requires VMID in descriptor to be enabled for the specific UDMA
* Target-ID to be assigned to the packet descriptors
* Requires Target-ID in descriptor to be enabled for the specific UDMA
* queue.
*/
uint16_t vmid;
uint16_t tgtid;
uint32_t rx_header_len; /**< header buffer length of rx packet, not used */
struct al_eth_meta_data *meta; /**< if null, then no meta added */
@ -434,6 +435,7 @@ struct al_hal_eth_adapter{
enum al_eth_mdio_type mdio_type; /**< mdio protocol type */
al_bool shared_mdio_if; /**< when AL_TRUE, the mdio interface is shared with other controllers.*/
uint8_t curr_lt_unit;
uint8_t serdes_lane;
#ifdef AL_ETH_EX
struct al_eth_ex_state ex_state;
#endif
@ -452,6 +454,8 @@ struct al_eth_adapter_params{
* can be null if the function is virtual
*/
char *name; /**< the upper layer must keep the string area */
uint8_t serdes_lane; /**< serdes lane (relevant to 25G macs only) */
};
/* adapter management */
@ -563,6 +567,39 @@ int al_eth_mac_stop(struct al_hal_eth_adapter *adapter);
*/
int al_eth_mac_start(struct al_hal_eth_adapter *adapter);
/**
* Perform gearbox reset for tx lanes And/Or Rx lanes.
* applicable only when the controller is connected to srds25G.
* This reset should be performed after each operation that changes the clocks
* (such as serdes reset, mac stop, etc.)
*
* @param adapter pointer to the private structure.
* @param tx_reset assert and de-assert reset for tx lanes
* @param rx_reset assert and de-assert reset for rx lanes
*/
void al_eth_gearbox_reset(struct al_hal_eth_adapter *adapter, al_bool tx_reset, al_bool rx_reset);
/**
* Enable / Disable forward error correction (FEC)
*
* @param adapter pointer to the private structure.
* @param enable true to enable FEC. false to disable FEC.
*
* @return 0 on success. negative error on failure.
*/
int al_eth_fec_enable(struct al_hal_eth_adapter *adapter, al_bool enable);
/**
* Get forward error correction (FEC) statistics
*
* @param adapter pointer to the private structure.
* @param corrected number of bits been corrected by the FEC
* @param uncorrectable number of bits that FEC couldn't correct.
*
* @return 0 on success. negative error on failure.
*/
int al_eth_fec_stats_get(struct al_hal_eth_adapter *adapter,
uint32_t *corrected, uint32_t *uncorrectable);
/**
* get the adapter capabilities (speed, duplex,..)
@ -1333,6 +1370,7 @@ struct al_eth_eee_params{
uint32_t tx_eee_timer; /**< time in cycles the interface delays prior to entering eee state */
uint32_t min_interval; /**< minimum interval in cycles between two eee states */
uint32_t stop_cnt; /**< time in cycles to stop Tx mac i/f after getting out of eee state */
al_bool fast_wake; /**< fast_wake is only applicable to 40/50G, otherwise the mode is deep_sleep */
};
/**
@ -1609,6 +1647,8 @@ int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter,
/* link */
struct al_eth_link_status {
al_bool link_up;
al_bool local_fault;
al_bool remote_fault;
};
/**
@ -1622,7 +1662,19 @@ struct al_eth_link_status {
*
* @return return 0 on success. otherwise on failure.
*/
int al_eth_link_status_get(struct al_hal_eth_adapter *adapter, struct al_eth_link_status *status);
int al_eth_link_status_get(struct al_hal_eth_adapter *adapter,
struct al_eth_link_status *status);
/**
* clear link status
*
* this function clear latched status of the link.
*
* @param adapter pointer to the private structure.
*
* @return return 0 if supported.
*/
int al_eth_link_status_clear(struct al_hal_eth_adapter *adapter);
/**
* Set LEDs to represent link status.
@ -1929,6 +1981,7 @@ enum al_eth_board_media_type {
AL_ETH_BOARD_MEDIA_TYPE_AUTO_DETECT_AUTO_SPEED = 5,
AL_ETH_BOARD_MEDIA_TYPE_SGMII_2_5G = 6,
AL_ETH_BOARD_MEDIA_TYPE_NBASE_T = 7,
AL_ETH_BOARD_MEDIA_TYPE_25G = 8,
};
enum al_eth_board_mdio_freq {
@ -1961,13 +2014,18 @@ enum al_eth_retimer_channel {
AL_ETH_RETIMER_CHANNEL_B = 1,
AL_ETH_RETIMER_CHANNEL_C = 2,
AL_ETH_RETIMER_CHANNEL_D = 3,
AL_ETH_RETIMER_CHANNEL_MAX = 4
AL_ETH_RETIMER_CHANNEL_E = 4,
AL_ETH_RETIMER_CHANNEL_F = 5,
AL_ETH_RETIMER_CHANNEL_G = 6,
AL_ETH_RETIMER_CHANNEL_H = 7,
AL_ETH_RETIMER_CHANNEL_MAX = 8
};
/* list of supported retimers */
enum al_eth_retimer_type {
AL_ETH_RETIMER_BR_210 = 0,
AL_ETH_RETIMER_BR_410 = 1,
AL_ETH_RETIMER_DS_25 = 2,
AL_ETH_RETIMER_TYPE_MAX = 4,
};
@ -1999,10 +2057,12 @@ struct al_eth_board_params {
al_bool retimer_exist; /**< retimer is exist on the board */
uint8_t retimer_bus_id; /**< in what i2c bus the retimer is on */
uint8_t retimer_i2c_addr; /**< i2c address of the retimer */
enum al_eth_retimer_channel retimer_channel; /**< what channel connected to this port */
enum al_eth_retimer_channel retimer_channel; /**< what channel connected to this port (Rx) */
al_bool dac; /**< assume direct attached cable is connected if auto detect is off or failed */
uint8_t dac_len; /**< assume this cable length if auto detect is off or failed */
enum al_eth_retimer_type retimer_type; /**< the type of the specific retimer */
enum al_eth_retimer_channel retimer_tx_channel; /**< what channel connected to this port (Tx) */
uint8_t gpio_sfp_present; /**< gpio number of sfp present for this port. 0 if not exist */
};
/**

View File

@ -54,6 +54,42 @@ extern "C" {
* Unit Registers
*/
struct al_eth_mac_1g_stats {
uint32_t reserved1[2];
uint32_t aFramesTransmittedOK; /* 0x68 */
uint32_t aFramesReceivedOK; /* 0x6c */
uint32_t aFrameCheckSequenceErrors; /* 0x70 */
uint32_t aAlignmentErrors; /* 0x74 */
uint32_t aOctetsTransmittedOK; /* 0x78 */
uint32_t aOctetsReceivedOK; /* 0x7c */
uint32_t aPAUSEMACCtrlFramesTransmitted; /* 0x80 */
uint32_t aPAUSEMACCtrlFramesReceived; /* 0x84 */
uint32_t ifInErrors ; /* 0x88 */
uint32_t ifOutErrors; /* 0x8c */
uint32_t ifInUcastPkts; /* 0x90 */
uint32_t ifInMulticastPkts; /* 0x94 */
uint32_t ifInBroadcastPkts; /* 0x98 */
uint32_t reserved2;
uint32_t ifOutUcastPkts; /* 0xa0 */
uint32_t ifOutMulticastPkts; /* 0xa4 */
uint32_t ifOutBroadcastPkts; /* 0xa8 */
uint32_t etherStatsDropEvents; /* 0xac */
uint32_t etherStatsOctets; /* 0xb0 */
uint32_t etherStatsPkts; /* 0xb4 */
uint32_t etherStatsUndersizePkts; /* 0xb8 */
uint32_t etherStatsOversizePkts; /* 0xbc */
uint32_t etherStatsPkts64Octets; /* 0xc0 */
uint32_t etherStatsPkts65to127Octets; /* 0xc4 */
uint32_t etherStatsPkts128to255Octets; /* 0xc8 */
uint32_t etherStatsPkts256to511Octets; /* 0xcc */
uint32_t etherStatsPkts512to1023Octets; /* 0xd0 */
uint32_t etherStatsPkts1024to1518Octets; /* 0xd4 */
uint32_t etherStatsPkts1519toX; /* 0xd8 */
uint32_t etherStatsJabbers; /* 0xdc */
uint32_t etherStatsFragments; /* 0xe0 */
uint32_t reserved3[71];
};
struct al_eth_mac_1g {
/* [0x0] */
uint32_t rev;
@ -82,12 +118,202 @@ struct al_eth_mac_1g {
uint32_t reg_stat;
uint32_t tx_ipg_len;
/* [0x60] */
uint32_t Reserved1[104];
struct al_eth_mac_1g_stats stats;
/* [0x200] */
uint32_t phy_regs_base;
uint32_t Reserved2[127];
};
struct al_eth_mac_10g_stats_v2 {
uint32_t aFramesTransmittedOK; /* 0x80 */
uint32_t reserved1;
uint32_t aFramesReceivedOK; /* 0x88 */
uint32_t reserved2;
uint32_t aFrameCheckSequenceErrors; /* 0x90 */
uint32_t reserved3;
uint32_t aAlignmentErrors; /* 0x98 */
uint32_t reserved4;
uint32_t aPAUSEMACCtrlFramesTransmitted; /* 0xa0 */
uint32_t reserved5;
uint32_t aPAUSEMACCtrlFramesReceived; /* 0xa8 */
uint32_t reserved6;
uint32_t aFrameTooLongErrors; /* 0xb0 */
uint32_t reserved7;
uint32_t aInRangeLengthErrors; /* 0xb8 */
uint32_t reserved8;
uint32_t VLANTransmittedOK; /* 0xc0 */
uint32_t reserved9;
uint32_t VLANReceivedOK; /* 0xc8 */
uint32_t reserved10;
uint32_t ifOutOctetsL; /* 0xd0 */
uint32_t ifOutOctetsH; /* 0xd4 */
uint32_t ifInOctetsL; /* 0xd8 */
uint32_t ifInOctetsH; /* 0xdc */
uint32_t ifInUcastPkts; /* 0xe0 */
uint32_t reserved11;
uint32_t ifInMulticastPkts; /* 0xe8 */
uint32_t reserved12;
uint32_t ifInBroadcastPkts; /* 0xf0 */
uint32_t reserved13;
uint32_t ifOutErrors; /* 0xf8 */
uint32_t reserved14[3];
uint32_t ifOutUcastPkts; /* 0x108 */
uint32_t reserved15;
uint32_t ifOutMulticastPkts; /* 0x110 */
uint32_t reserved16;
uint32_t ifOutBroadcastPkts; /* 0x118 */
uint32_t reserved17;
uint32_t etherStatsDropEvents; /* 0x120 */
uint32_t reserved18;
uint32_t etherStatsOctets; /* 0x128 */
uint32_t reserved19;
uint32_t etherStatsPkts; /* 0x130 */
uint32_t reserved20;
uint32_t etherStatsUndersizePkts; /* 0x138 */
uint32_t reserved21;
uint32_t etherStatsPkts64Octets; /* 0x140 */
uint32_t reserved22;
uint32_t etherStatsPkts65to127Octets; /* 0x148 */
uint32_t reserved23;
uint32_t etherStatsPkts128to255Octets; /* 0x150 */
uint32_t reserved24;
uint32_t etherStatsPkts256to511Octets; /* 0x158 */
uint32_t reserved25;
uint32_t etherStatsPkts512to1023Octets; /* 0x160 */
uint32_t reserved26;
uint32_t etherStatsPkts1024to1518Octets; /* 0x168 */
uint32_t reserved27;
uint32_t etherStatsPkts1519toX; /* 0x170 */
uint32_t reserved28;
uint32_t etherStatsOversizePkts; /* 0x178 */
uint32_t reserved29;
uint32_t etherStatsJabbers; /* 0x180 */
uint32_t reserved30;
uint32_t etherStatsFragments; /* 0x188 */
uint32_t reserved31;
uint32_t ifInErrors; /* 0x190 */
uint32_t reserved32[91];
};
struct al_eth_mac_10g_stats_v3_rx {
uint32_t etherStatsOctets; /* 0x00 */
uint32_t reserved2;
uint32_t ifOctetsL; /* 0x08 */
uint32_t ifOctetsH; /* 0x0c */
uint32_t aAlignmentErrors; /* 0x10 */
uint32_t reserved4;
uint32_t aPAUSEMACCtrlFrames; /* 0x18 */
uint32_t reserved5;
uint32_t FramesOK; /* 0x20 */
uint32_t reserved6;
uint32_t CRCErrors; /* 0x28 */
uint32_t reserved7;
uint32_t VLANOK; /* 0x30 */
uint32_t reserved8;
uint32_t ifInErrors; /* 0x38 */
uint32_t reserved9;
uint32_t ifInUcastPkts; /* 0x40 */
uint32_t reserved10;
uint32_t ifInMulticastPkts; /* 0x48 */
uint32_t reserved11;
uint32_t ifInBroadcastPkts; /* 0x50 */
uint32_t reserved12;
uint32_t etherStatsDropEvents; /* 0x58 */
uint32_t reserved13;
uint32_t etherStatsPkts; /* 0x60 */
uint32_t reserved14;
uint32_t etherStatsUndersizePkts; /* 0x68 */
uint32_t reserved15;
uint32_t etherStatsPkts64Octets; /* 0x70 */
uint32_t reserved16;
uint32_t etherStatsPkts65to127Octets; /* 0x78 */
uint32_t reserved17;
uint32_t etherStatsPkts128to255Octets; /* 0x80 */
uint32_t reserved18;
uint32_t etherStatsPkts256to511Octets; /* 0x88 */
uint32_t reserved19;
uint32_t etherStatsPkts512to1023Octets; /* 0x90 */
uint32_t reserved20;
uint32_t etherStatsPkts1024to1518Octets; /* 0x98 */
uint32_t reserved21;
uint32_t etherStatsPkts1519toMax; /* 0xa0 */
uint32_t reserved22;
uint32_t etherStatsOversizePkts; /* 0xa8 */
uint32_t reserved23;
uint32_t etherStatsJabbers; /* 0xb0 */
uint32_t reserved24;
uint32_t etherStatsFragments; /* 0xb8 */
uint32_t reserved25;
uint32_t aMACControlFramesReceived; /* 0xc0 */
uint32_t reserved26;
uint32_t aFrameTooLong; /* 0xc8 */
uint32_t reserved27;
uint32_t aInRangeLengthErrors; /* 0xd0 */
uint32_t reserved28;
uint32_t reserved29[10];
};
struct al_eth_mac_10g_stats_v3_tx {
uint32_t etherStatsOctets; /* 0x00 */
uint32_t reserved30;
uint32_t ifOctetsL; /* 0x08 */
uint32_t ifOctetsH; /* 0x0c */
uint32_t aAlignmentErrors; /* 0x10 */
uint32_t reserved32;
uint32_t aPAUSEMACCtrlFrames; /* 0x18 */
uint32_t reserved33;
uint32_t FramesOK; /* 0x20 */
uint32_t reserved34;
uint32_t CRCErrors; /* 0x28 */
uint32_t reserved35;
uint32_t VLANOK; /* 0x30 */
uint32_t reserved36;
uint32_t ifOutErrors; /* 0x38 */
uint32_t reserved37;
uint32_t ifUcastPkts; /* 0x40 */
uint32_t reserved38;
uint32_t ifMulticastPkts; /* 0x48 */
uint32_t reserved39;
uint32_t ifBroadcastPkts; /* 0x50 */
uint32_t reserved40;
uint32_t etherStatsDropEvents; /* 0x58 */
uint32_t reserved41;
uint32_t etherStatsPkts; /* 0x60 */
uint32_t reserved42;
uint32_t etherStatsUndersizePkts; /* 0x68 */
uint32_t reserved43;
uint32_t etherStatsPkts64Octets; /* 0x70 */
uint32_t reserved44;
uint32_t etherStatsPkts65to127Octets; /* 0x78 */
uint32_t reserved45;
uint32_t etherStatsPkts128to255Octets; /* 0x80 */
uint32_t reserved46;
uint32_t etherStatsPkts256to511Octets; /* 0x88 */
uint32_t reserved47;
uint32_t etherStatsPkts512to1023Octets; /* 0x90 */
uint32_t reserved48;
uint32_t etherStatsPkts1024to1518Octets; /* 0x98 */
uint32_t reserved49;
uint32_t etherStatsPkts1519toTX_MTU; /* 0xa0 */
uint32_t reserved50;
uint32_t reserved51[4];
uint32_t aMACControlFrames; /* 0xc0 */
uint32_t reserved52[15];
};
struct al_eth_mac_10g_stats_v3 {
uint32_t reserved1[32];
/* 0x100 */
struct al_eth_mac_10g_stats_v3_rx rx;
/* 0x200 */
struct al_eth_mac_10g_stats_v3_tx tx;
};
union al_eth_mac_10g_stats {
struct al_eth_mac_10g_stats_v2 v2;
struct al_eth_mac_10g_stats_v3 v3;
};
struct al_eth_mac_10g {
/* [0x0] */
uint32_t rev;
@ -131,8 +357,7 @@ struct al_eth_mac_10g {
uint32_t Reserved2;
uint32_t ts_timestamp;
/* [0x80] */
uint32_t Reserved3[160];
union al_eth_mac_10g_stats stats;
/* [0x300] */
uint32_t control;
@ -442,16 +667,45 @@ struct al_eth_mac_regs {
* Registers Fields
*/
/**** control register (1G mac) ****/
/**** 1G MAC registers ****/
/* cmd_cfg */
#define ETH_1G_MAC_CMD_CFG_TX_ENA (1 << 0)
#define ETH_1G_MAC_CMD_CFG_RX_ENA (1 << 1)
/* enable Half Duplex */
#define AL_ETH_1G_MAC_CTRL_HD_EN (1 << 10)
#define ETH_1G_MAC_CMD_CFG_HD_EN (1 << 10)
/* enable 1G speed */
#define AL_ETH_1G_MAC_CTRL_1G_SPD (1 << 3)
#define ETH_1G_MAC_CMD_CFG_1G_SPD (1 << 3)
/* enable 10M speed */
#define AL_ETH_1G_MAC_CTRL_10M_SPD (1 << 25)
#define ETH_1G_MAC_CMD_CFG_10M_SPD (1 << 25)
/**** 10G MAC registers ****/
/* cmd_cfg */
#define ETH_10G_MAC_CMD_CFG_TX_ENA (1 << 0)
#define ETH_10G_MAC_CMD_CFG_RX_ENA (1 << 1)
#define ETH_10G_MAC_CMD_CFG_WAN_MODE (1 << 3)
#define ETH_10G_MAC_CMD_CFG_PROMIS_EN (1 << 4)
#define ETH_10G_MAC_CMD_CFG_PAD_EN (1 << 5)
#define ETH_10G_MAC_CMD_CFG_CRC_FWD (1 << 6)
#define ETH_10G_MAC_CMD_CFG_PAUSE_FWD (1 << 7)
#define ETH_10G_MAC_CMD_CFG_PAUSE_IGNORE (1 << 8)
#define ETH_10G_MAC_CMD_CFG_TX_ADDR_INS (1 << 9)
#define ETH_10G_MAC_CMD_CFG_LOOP_ENA (1 << 10)
#define ETH_10G_MAC_CMD_CFG_TX_PAD_EN (1 << 11)
#define ETH_10G_MAC_CMD_CFG_SW_RESET (1 << 12)
#define ETH_10G_MAC_CMD_CFG_CNTL_FRM_ENA (1 << 13)
#define ETH_10G_MAC_CMD_CFG_RX_ERR_DISC (1 << 14)
#define ETH_10G_MAC_CMD_CFG_PHY_TXENA (1 << 15)
#define ETH_10G_MAC_CMD_CFG_FORCE_SEND_IDLE (1 << 16)
#define ETH_10G_MAC_CMD_CFG_NO_LGTH_CHECK (1 << 17)
#define ETH_10G_MAC_CMD_CFG_COL_CNT_EXT (1 << 18)
#define ETH_10G_MAC_CMD_CFG_PFC_MODE (1 << 19)
#define ETH_10G_MAC_CMD_CFG_PAUSE_PFC_COMP (1 << 20)
#define ETH_10G_MAC_CMD_CFG_SFD_ANY (1 << 21)
#define ETH_10G_MAC_CMD_CFG_TX_FLUSH (1 << 22)
#define ETH_10G_MAC_CMD_CFG_TX_LOWP_ENA (1 << 23)
#define ETH_10G_MAC_CMD_CFG_REG_LOWP_RXEMPTY (1 << 24)
#define ETH_10G_MAC_CMD_CFG_SHORT_DISCARD (1 << 25)
/**** 10G MAC register ****/
/* mdio_cfg_status */
#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK 0x0000001c
#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT 2
@ -465,6 +719,27 @@ struct al_eth_mac_regs {
#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_13_CLK 6
#define ETH_10G_MAC_MDIO_CFG_HOLD_TIME_15_CLK 7
/* control */
#define ETH_10G_MAC_CONTROL_AN_EN_MASK 0x00001000
#define ETH_10G_MAC_CONTROL_AN_EN_SHIFT 12
/* if_mode */
#define ETH_10G_MAC_IF_MODE_SGMII_EN_MASK 0x00000001
#define ETH_10G_MAC_IF_MODE_SGMII_EN_SHIFT 0
#define ETH_10G_MAC_IF_MODE_SGMII_AN_MASK 0x00000002
#define ETH_10G_MAC_IF_MODE_SGMII_AN_SHIFT 1
#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_MASK 0x0000000c
#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_SHIFT 2
#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_MASK 0x00000010
#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_SHIFT 4
#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_10M 0
#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_100M 1
#define ETH_10G_MAC_IF_MODE_SGMII_SPEED_1G 2
#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_FULL 0
#define ETH_10G_MAC_IF_MODE_SGMII_DUPLEX_HALF 1
/**** version register ****/
/* Revision number (Minor) */
#define ETH_MAC_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
@ -1794,9 +2069,13 @@ struct al_eth_mac_regs {
/*** PCS Core registers addresses ***/
/* 40g control/status */
#define ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR 0x00000000
/* 40g EEE control and capability */
#define ETH_MAC_GEN_V3_PCS_40G_EEE_CONTROL_ADDR 0x00000028
/* 10g control_1 */
#define ETH_MAC_KR_PCS_CONTROL_1_ADDR 0x00000000
#define ETH_MAC_KR_PCS_BASE_R_STATUS2 0x00000021
#define ETH_MAC_KR_AN_MILLISECONDS_COUNTER_ADDR 0x00008000
#define ETH_MAC_AN_LT_MILLISECONDS_COUNTER_ADDR 0x00000020

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,291 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_iofic.c
*
* @brief interrupt controller hal
*
*/
#include "al_hal_iofic.h"
#include "al_hal_iofic_regs.h"
/*
* configure the interrupt registers, interrupts will are kept masked
*/
int al_iofic_config(void __iomem *regs_base, int group, uint32_t flags)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
al_reg_write32(&regs->ctrl[group].int_control_grp, flags);
return 0;
}
/*
* configure the moderation timer resolution for a given group
*/
int al_iofic_moder_res_config(void __iomem *regs_base, int group,
uint8_t resolution)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
AL_REG_FIELD_SET(reg,
INT_CONTROL_GRP_MOD_RES_MASK,
INT_CONTROL_GRP_MOD_RES_SHIFT,
resolution);
al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
return 0;
}
/*
* configure the moderation timer interval for a given legacy interrupt group
*/
int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group,
uint8_t interval)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
AL_REG_FIELD_SET(reg,
INT_CONTROL_GRP_MOD_INTV_MASK,
INT_CONTROL_GRP_MOD_INTV_SHIFT,
interval);
al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
return 0;
}
/*
* configure the moderation timer interval for a given msix vector.
*/
int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
uint8_t vector, uint8_t interval)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
reg = al_reg_read32(&regs->grp_int_mod[group][vector].grp_int_mod_reg);
AL_REG_FIELD_SET(reg,
INT_MOD_INTV_MASK,
INT_MOD_INTV_SHIFT,
interval);
al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_mod_reg, reg);
return 0;
}
/*
* configure the vmid attributes for a given msix vector.
*/
int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t vmid, uint8_t vmid_en)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg = 0;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
AL_REG_FIELD_SET(reg,
INT_MSIX_VMID_MASK,
INT_MSIX_VMID_SHIFT,
vmid);
AL_REG_BIT_VAL_SET(reg,
INT_MSIX_VMID_EN_SHIFT,
vmid_en);
al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_vmid_reg, reg);
return 0;
}
/*
* return the offset of the unmask register for a given group
*/
uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
return &regs->ctrl[group].int_mask_clear_grp;
}
/*
* unmask specific interrupts for a given group
*/
void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
/*
* use the mask clear register, no need to read the mask register
* itself. write 0 to unmask, 1 has no effect
*/
al_reg_write32_relaxed(&regs->ctrl[group].int_mask_clear_grp, ~mask);
}
/*
* mask specific interrupts for a given group
*/
void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
reg = al_reg_read32(&regs->ctrl[group].int_mask_grp);
al_reg_write32(&regs->ctrl[group].int_mask_grp, reg | mask);
}
/*
* read the mask for a given group
*/
uint32_t al_iofic_read_mask(void __iomem *regs_base, int group)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
return al_reg_read32(&regs->ctrl[group].int_mask_grp);
}
/*
* read interrupt cause register for a given group
*/
uint32_t al_iofic_read_cause(void __iomem *regs_base, int group)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
return al_reg_read32(&regs->ctrl[group].int_cause_grp);
}
/*
* clear bits in the interrupt cause register for a given group
*/
void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
/* inverse mask, writing 1 has no effect */
al_reg_write32(&regs->ctrl[group].int_cause_grp, ~mask);
}
/*
* Set the cause register for a given group
*/
void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
al_reg_write32(&regs->ctrl[group].int_cause_set_grp, mask);
}
/*
* unmask specific interrupts from aborting the udma a given group
*/
void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
al_reg_write32(&regs->ctrl[group].int_abort_msk_grp, mask);
}
/*
* trigger all interrupts that are waiting for moderation timers to expire
*/
void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group)
{
struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
uint32_t reg = 0;
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
al_assert(regs_base);
al_assert(group < AL_IOFIC_MAX_GROUPS);
reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
reg |= INT_CONTROL_GRP_MOD_RST;
al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
}
/** @} end of interrupt controller group */

View File

@ -0,0 +1,222 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_interrupts Common I/O Fabric Interrupt Controller
* This HAL provides the API for programming the Common I/O Fabric Interrupt
* Controller (IOFIC) found in most of the units attached to the I/O Fabric of
* Alpine platform
* @{
* @file al_hal_iofic.h
*
* @brief Header file for the interrupt controller that's embedded in various units
*
*/
#ifndef __AL_HAL_IOFIC_H__
#define __AL_HAL_IOFIC_H__
#include <al_hal_common.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#define AL_IOFIC_MAX_GROUPS 4
/*
* Configurations
*/
/**
* Configure the interrupt controller registers, actual interrupts are still
* masked at this stage.
*
* @param regs_base regs pointer to interrupt controller registers
* @param group the interrupt group.
* @param flags flags of Interrupt Control Register
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_config(void __iomem *regs_base, int group,
uint32_t flags);
/**
* configure the moderation timer resolution for a given group
* Applies for both msix and legacy mode.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param resolution resolution of the timer interval, the resolution determines the rate
* of decrementing the interval timer, setting value N means that the interval
* timer will be decremented each (N+1) * (0.68) micro seconds.
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_moder_res_config(void __iomem *regs_base, int group,
uint8_t resolution);
/**
* configure the moderation timer interval for a given legacy interrupt group
*
* @param regs_base regs pointer to unit registers
* @param group the interrupt group
* @param interval between interrupts in resolution units. 0 disable
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group,
uint8_t interval);
/**
* configure the moderation timer interval for a given msix vector
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param vector vector index
* @param interval interval between interrupts, 0 disable
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
uint8_t vector, uint8_t interval);
/**
* configure the vmid attributes for a given msix vector.
*
* @param group the interrupt group
* @param vector index
* @param vmid the vmid value
* @param vmid_en take vmid from the intc
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t vmid, uint8_t vmid_en);
/**
* return the offset of the unmask register for a given group.
* this function can be used when the upper layer wants to directly
* access the unmask regiter and bypass the al_iofic_unmask() API.
*
* @param regs_base regs pointer to unit registers
* @param group the interrupt group
* @return the offset of the unmask register.
*/
uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group);
/**
* unmask specific interrupts for a given group
* this functions guarantees atomic operations, it is performance optimized as
* it will not require read-modify-write. The unmask done using the interrupt
* mask clear register, so it's safe to call it while the mask is changed by
* the HW (auto mask) or another core.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to unmask, set bits will be unmasked.
*/
void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask);
/**
* mask specific interrupts for a given group
* this functions modifies interrupt mask register, the callee must make sure
* the mask is not changed by another cpu.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to mask, set bits will be masked.
*/
void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask);
/**
* read the mask register for a given group
* this functions return the interrupt mask register
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
uint32_t al_iofic_read_mask(void __iomem *regs_base, int group);
/**
* read interrupt cause register for a given group
* this will clear the set bits if the Clear on Read mode enabled.
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
uint32_t al_iofic_read_cause(void __iomem *regs_base, int group);
/**
* clear bits in the interrupt cause register for a given group
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of bits to be cleared, set bits will be cleared.
*/
void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask);
/**
* set the cause register for a given group
* this function set the cause register. It will generate an interrupt (if
* the the interrupt isn't masked )
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of bits to be set.
*/
void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask);
/**
* unmask specific interrupts from aborting the udma a given group
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to mask
*/
void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask);
/**
* trigger all interrupts that are waiting for moderation timers to expire
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group);
#endif
/** @} end of interrupt controller group */

View File

@ -0,0 +1,127 @@
/*_
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_IOFIC_REG_H
#define __AL_HAL_IOFIC_REG_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct al_iofic_grp_ctrl {
uint32_t int_cause_grp; /* Interrupt Cause RegisterSet by hardware */
uint32_t rsrvd1;
uint32_t int_cause_set_grp; /* Interrupt Cause Set RegisterWriting 1 to a bit in t ... */
uint32_t rsrvd2;
uint32_t int_mask_grp; /* Interrupt Mask RegisterIf Auto-mask control bit =TR ... */
uint32_t rsrvd3;
uint32_t int_mask_clear_grp; /* Interrupt Mask Clear RegisterUsed when auto-mask co ... */
uint32_t rsrvd4;
uint32_t int_status_grp; /* Interrupt status RegisterThis register latch the st ... */
uint32_t rsrvd5;
uint32_t int_control_grp; /* Interrupt Control Register */
uint32_t rsrvd6;
uint32_t int_abort_msk_grp; /* Interrupt Mask RegisterEach bit in this register ma ... */
uint32_t rsrvd7;
uint32_t int_log_msk_grp; /* Interrupt Log RegisterEach bit in this register mas ... */
uint32_t rsrvd8;
};
struct al_iofic_grp_mod {
uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */
uint32_t grp_int_vmid_reg;
};
struct al_iofic_regs {
struct al_iofic_grp_ctrl ctrl[0];
uint32_t rsrvd1[0x400 >> 2];
struct al_iofic_grp_mod grp_int_mod[0][32];
};
/*
* Registers Fields
*/
/**** int_control_grp register ****/
/* When Clear_on_Read =1, All bits of Cause register ... */
#define INT_CONTROL_GRP_CLEAR_ON_READ (1 << 0)
/* (must be set only when MSIX is enabled)When Auto-Ma ... */
#define INT_CONTROL_GRP_AUTO_MASK (1 << 1)
/* Auto_Clear (RW)When Auto-Clear =1, the bits in the ... */
#define INT_CONTROL_GRP_AUTO_CLEAR (1 << 2)
/* When Set_on_Posedge =1, the bits in the interrupt c ... */
#define INT_CONTROL_GRP_SET_ON_POSEDGE (1 << 3)
/* When Moderation_Reset =1, all Moderation timers ass ... */
#define INT_CONTROL_GRP_MOD_RST (1 << 4)
/* When mask_msi_x =1, No MSI-X from this group is sen ... */
#define INT_CONTROL_GRP_MASK_MSI_X (1 << 5)
/* MSI-X AWID value, same ID for all cause bits */
#define INT_CONTROL_GRP_AWID_MASK 0x00000F00
#define INT_CONTROL_GRP_AWID_SHIFT 8
/* This value determines the interval between interrup ... */
#define INT_CONTROL_GRP_MOD_INTV_MASK 0x00FF0000
#define INT_CONTROL_GRP_MOD_INTV_SHIFT 16
/* This value determines the Moderation_Timer_Clock sp ... */
#define INT_CONTROL_GRP_MOD_RES_MASK 0x0F000000
#define INT_CONTROL_GRP_MOD_RES_SHIFT 24
/**** grp_int_mod_reg register ****/
/* Interrupt Moderation Interval registerDedicated reg ... */
#define INT_MOD_INTV_MASK 0x000000FF
#define INT_MOD_INTV_SHIFT 0
/**** grp_int_vmid_reg register ****/
/* Interrupt vmid value registerDedicated reg ... */
#define INT_MSIX_VMID_MASK 0x0000FFFF
#define INT_MSIX_VMID_SHIFT 0
/* Interrupt vmid_en value registerDedicated reg ... */
#define INT_MSIX_VMID_EN_SHIFT 31
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_IOFIC_REG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,271 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _AL_HAL_PCIE_INTERRUPTS_H_
#define _AL_HAL_PCIE_INTERRUPTS_H_
#include "al_hal_common.h"
#include "al_hal_pcie.h"
#include "al_hal_iofic.h"
/**
* @defgroup group_pcie_interrupts PCIe interrupts
* @ingroup grouppcie
* @{
* The PCIe interrupts HAL can be used to control PCIe unit interrupts.
* There are 5 groups of interrupts: app group A, B, C, D and AXI.
* Only 2 interrupts go from the pcie unit to the GIC:
* 1. Summary for all the int groups (AXI+APP CORE).
* 2. INTA assert/deassert (RC only).
* For the specific GIC interrupt line, please check the architecture reference
* manual.
* The reset mask state of all interrupts is: Masked
*
* @file al_hal_pcie_interrupts.h
*
*/
/**
* PCIe interrupt groups
*/
enum al_pcie_int_group {
AL_PCIE_INT_GRP_A,
AL_PCIE_INT_GRP_B,
AL_PCIE_INT_GRP_C, /* Rev3 only */
AL_PCIE_INT_GRP_D, /* Rev3 only */
AL_PCIE_INT_GRP_AXI_A,
};
/**
* App group A interrupts mask - don't change
* All interrupts not listed below should be masked
*/
enum al_pcie_app_int_grp_a {
/** [RC only] Deassert_INTD received */
AL_PCIE_APP_INT_DEASSERT_INTD = AL_BIT(0),
/** [RC only] Deassert_INTC received */
AL_PCIE_APP_INT_DEASSERT_INTC = AL_BIT(1),
/** [RC only] Deassert_INTB received */
AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2),
/**
* [RC only] Deassert_INTA received - there's a didcated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3),
/** [RC only] Assert_INTD received */
AL_PCIE_APP_INT_ASSERT_INTD = AL_BIT(4),
/** [RC only] Assert_INTC received */
AL_PCIE_APP_INT_ASSERT_INTC = AL_BIT(5),
/** [RC only] Assert_INTB received */
AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6),
/**
* [RC only] Assert_INTA received - there's a didcated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7),
/** [RC only] MSI Controller Interrupt */
AL_PCIE_APP_INT_MSI_CNTR_RCV_INT = AL_BIT(8),
/** [EP only] MSI sent grant */
AL_PCIE_APP_INT_MSI_TRNS_GNT = AL_BIT(9),
/** [RC only] System error detected (ERR_COR, ERR_FATAL, ERR_NONFATAL) */
AL_PCIE_APP_INT_SYS_ERR_RC = AL_BIT(10),
/** [EP only] Software initiates FLR on a Physical Function */
AL_PCIE_APP_INT_FLR_PF_ACTIVE = AL_BIT(11),
/** [RC only] Root Error Command register assertion notification */
AL_PCIE_APP_INT_AER_RC_ERR = AL_BIT(12),
/** [RC only] Root Error Command register assertion notification With MSI or MSIX enabled */
AL_PCIE_APP_INT_AER_RC_ERR_MSI = AL_BIT(13),
/** [RC only] PME Status bit assertion in the Root Status register With INTA */
AL_PCIE_APP_INT_PME_INT = AL_BIT(15),
/** [RC only] PME Status bit assertion in the Root Status register With MSI or MSIX enabled */
AL_PCIE_APP_INT_PME_MSI = AL_BIT(16),
/** [RC/EP] The core assert link down event, whenever the link is going down */
AL_PCIE_APP_INT_LINK_DOWN = AL_BIT(21),
/** [EP only] When the EP gets a command to shut down, signal the software to block any new TLP. */
AL_PCIE_APP_INT_PM_XTLH_BLOCK_TLP = AL_BIT(22),
/** [RC/EP] PHY/MAC link up */
AL_PCIE_APP_INT_XMLH_LINK_UP = AL_BIT(23),
/** [RC/EP] Data link up */
AL_PCIE_APP_INT_RDLH_LINK_UP = AL_BIT(24),
/** [RC/EP] The LTSSM is in RCVRY_LOCK state. */
AL_PCIE_APP_INT_LTSSM_RCVRY_STATE = AL_BIT(25),
/**
* [RC/EP] CFG write transaction to the configuration space by the RC peer
* For RC the int/ will be set from DBI write (internal SoC write)]
*/
AL_PCIE_APP_INT_CFG_WR = AL_BIT(26),
/** [EP only] CFG access in EP mode */
AL_PCIE_APP_INT_CFG_ACCESS = AL_BIT(31),
};
/**
* App group B interrupts mask - don't change
* All interrupts not listed below should be masked
*/
enum al_pcie_app_int_grp_b {
/** [RC only] PM_PME Message received */
AL_PCIE_APP_INT_GRP_B_PM_PME_MSG_RCVD = AL_BIT(0),
/** [RC only] PME_TO_Ack Message received */
AL_PCIE_APP_INT_GRP_B_PME_TO_ACK_MSG_RCVD = AL_BIT(1),
/** [EP only] PME_Turn_Off Message received */
AL_PCIE_APP_INT_GRP_B_PME_TURN_OFF_MSG_RCVD = AL_BIT(2),
/** [RC only] ERR_CORR Message received */
AL_PCIE_APP_INT_GRP_B_CORR_ERR_MSG_RCVD = AL_BIT(3),
/** [RC only] ERR_NONFATAL Message received */
AL_PCIE_APP_INT_GRP_B_NON_FTL_ERR_MSG_RCVD = AL_BIT(4),
/** [RC only] ERR_FATAL Message received */
AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7),
/** [EP only] Link Autonomous Bandwidth Status is updated */
AL_PCIE_APP_INT_GRP_B_LNK_BW_UPD = AL_BIT(12),
/** [EP only] Link Equalization Request bit in the Link Status 2 Register has been set */
AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13),
/** [RC/EP] OB Vendor message request is granted by the PCIe core */
AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14),
/** [RC only] CPL timeout from the PCIe core indiication */
AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15),
/** [RC/EP] Slave Response Composer Lookup Error */
AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16),
/** [RC/EP] Parity Error */
AL_PCIE_APP_INT_GRP_B_PARITY_ERR = AL_BIT(17),
/** [EP only] Speed change request */
AL_PCIE_APP_INT_GRP_B_SPEED_CHANGE = AL_BIT(31),
};
/**
* AXI interrupts mask - don't change
* These are internal errors that can happen on the internal chip interface
* between the PCIe port and the I/O Fabric over the AXI bus. The notion of
* master and slave refer to the PCIe port master interface towards the I/O
* Fabric (i.e. for inbound PCIe writes/reads toward the I/O Fabric), while the
* slave interface refer to the I/O Fabric to PCIe port interface where the
* internal chip DMAs and CPU cluster is initiating transactions.
* All interrupts not listed below should be masked.
*/
enum al_pcie_axi_int {
/** [RC/EP] Master Response Composer Lookup Error */
AL_PCIE_AXI_INT_MSTR_RESP_COMP_LKUP_ERR = AL_BIT(0),
/** [RC/EP] PARITY ERROR on the master data read channel */
AL_PCIE_AXI_INT_PARITY_ERR_MSTR_DATA_RD_CHNL = AL_BIT(2),
/** [RC/EP] PARITY ERROR on the slave addr read channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_RD_CHNL = AL_BIT(3),
/** [RC/EP] PARITY ERROR on the slave addr write channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_WR_CHNL = AL_BIT(4),
/** [RC/EP] PARITY ERROR on the slave data write channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_DATA_WR_CHNL = AL_BIT(5),
/** [RC only] Software error: ECAM write request with invalid bus number */
AL_PCIE_AXI_INT_ECAM_WR_REQ_INVLD_BUS_NUM = AL_BIT(7),
/** [RC only] Software error: ECAM read request with invalid bus number */
AL_PCIE_AXI_INT_ECAM_RD_REQ_INVLD_BUS_NUM = AL_BIT(8),
/** [RC/EP] Read AXI completion has ERROR */
AL_PCIE_AXI_INT_RD_AXI_COMPL_ERR = AL_BIT(11),
/** [RC/EP] Write AXI completion has ERROR */
AL_PCIE_AXI_INT_WR_AXI_COMPL_ERR = AL_BIT(12),
/** [RC/EP] Read AXI completion has timed out */
AL_PCIE_AXI_INT_RD_AXI_COMPL_TO = AL_BIT(13),
/** [RC/EP] Write AXI completion has timed out */
AL_PCIE_AXI_INT_WR_AXI_COMPL_TO = AL_BIT(14),
/** [RC/EP] Parity error AXI domain */
AL_PCIE_AXI_INT_AXI_DOM_PARITY_ERR = AL_BIT(15),
/** [RC/EP] POS error interrupt */
AL_PCIE_AXI_INT_POS_ERR = AL_BIT(16),
};
/**
* @brief Initialize and configure PCIe controller interrupts
* Doesn't change the mask state of the interrupts
* The reset mask state of all interrupts is: Masked
*
* @param pcie_port pcie port handle
*/
void al_pcie_ints_config(struct al_pcie_port *pcie_port);
/**
* Unmask PCIe app group interrupts
* @param pcie_port pcie_port pcie port handle
* @param int_group interrupt group
* @param int_mask int_mask interrupts to unmask ('1' to unmask)
*/
void al_pcie_app_int_grp_unmask(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_mask);
/**
* Mask PCIe app group interrupts
* @param pcie_port pcie_port pcie port handle
* @param int_group interrupt group
* @param int_mask int_mask interrupts to unmask ('1' to mask)
*/
void al_pcie_app_int_grp_mask(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_mask);
/**
* Clear the PCIe app group interrupt cause
* @param pcie_port pcie port handle
* @param int_group interrupt group
* @param int_cause interrupt cause
*/
void al_pcie_app_int_grp_cause_clear(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_cause);
/**
* Read PCIe app group interrupt cause
* @param pcie_port pcie port handle
* @param int_group interrupt group
* @return interrupt cause or 0 in case the group is not supported
*/
uint32_t al_pcie_app_int_grp_cause_read(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group);
#endif
/** @} end of group_pcie_interrupts group */

View File

@ -0,0 +1,594 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_PCIE_REGS_H__
#define __AL_HAL_PCIE_REGS_H__
/* Note: Definitions before the includes so axi/wrapper regs sees them */
/** Maximum physical functions supported */
#define REV1_2_MAX_NUM_OF_PFS 1
#define REV3_MAX_NUM_OF_PFS 4
#define AL_MAX_NUM_OF_PFS 4 /* the maximum between all Revisions */
#include "al_hal_pcie_axi_reg.h"
#ifndef AL_PCIE_EX
#include "al_hal_pcie_w_reg.h"
#else
#include "al_hal_pcie_w_reg_ex.h"
#endif
/**
* Revision IDs:
* ID_0: SlickRock M0
* ID_1: SlickRock A0
* ID_2: PeakRock x4
* ID_3: PeakRock x8
*/
#define AL_PCIE_REV_ID_0 0
#define AL_PCIE_REV_ID_1 1
#define AL_PCIE_REV_ID_2 2
#define AL_PCIE_REV_ID_3 3
#define AL_PCIE_AXI_REGS_OFFSET 0x0
#define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000
#define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000
#define AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET 0x2000
#define AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET 0x10000
/** Maximum number of lanes supported */
#define REV1_2_MAX_NUM_LANES 4
#define REV3_MAX_NUM_LANES 8
#define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */
struct al_pcie_core_iatu_regs {
uint32_t index;
uint32_t cr1;
uint32_t cr2;
uint32_t lower_base_addr;
uint32_t upper_base_addr;
uint32_t limit_addr;
uint32_t lower_target_addr;
uint32_t upper_target_addr;
uint32_t cr3;
uint32_t rsrvd[(0x270 - 0x224) >> 2];
};
struct al_pcie_core_port_regs {
uint32_t ack_lat_rply_timer;
uint32_t reserved1[(0x10 - 0x4) >> 2];
uint32_t port_link_ctrl;
uint32_t reserved2[(0x18 - 0x14) >> 2];
uint32_t timer_ctrl_max_func_num;
uint32_t filter_mask_reg_1;
uint32_t reserved3[(0x48 - 0x20) >> 2];
uint32_t vc0_posted_rcv_q_ctrl;
uint32_t vc0_non_posted_rcv_q_ctrl;
uint32_t vc0_comp_rcv_q_ctrl;
uint32_t reserved4[(0x10C - 0x54) >> 2];
uint32_t gen2_ctrl;
uint32_t reserved5[(0x190 - 0x110) >> 2];
uint32_t gen3_ctrl;
uint32_t gen3_eq_fs_lf;
uint32_t gen3_eq_preset_to_coef_map;
uint32_t gen3_eq_preset_idx;
uint32_t reserved6;
uint32_t gen3_eq_status;
uint32_t gen3_eq_ctrl;
uint32_t reserved7[(0x1B8 - 0x1AC) >> 2];
uint32_t pipe_loopback_ctrl;
uint32_t rd_only_wr_en;
uint32_t reserved8[(0x1D0 - 0x1C0) >> 2];
uint32_t axi_slave_err_resp;
uint32_t reserved9[(0x200 - 0x1D4) >> 2];
struct al_pcie_core_iatu_regs iatu;
uint32_t reserved10[(0x448 - 0x270) >> 2];
};
struct al_pcie_core_aer_regs {
/* 0x0 - PCI Express Extended Capability Header */
uint32_t header;
/* 0x4 - Uncorrectable Error Status Register */
uint32_t uncorr_err_stat;
/* 0x8 - Uncorrectable Error Mask Register */
uint32_t uncorr_err_mask;
/* 0xc - Uncorrectable Error Severity Register */
uint32_t uncorr_err_severity;
/* 0x10 - Correctable Error Status Register */
uint32_t corr_err_stat;
/* 0x14 - Correctable Error Mask Register */
uint32_t corr_err_mask;
/* 0x18 - Advanced Error Capabilities and Control Register */
uint32_t cap_and_ctrl;
/* 0x1c - Header Log Registers */
uint32_t header_log[4];
/* 0x2c - Root Error Command Register */
uint32_t root_err_cmd;
/* 0x30 - Root Error Status Register */
uint32_t root_err_stat;
/* 0x34 - Error Source Identification Register */
uint32_t err_src_id;
};
struct al_pcie_core_reg_space_rev_1_2 {
uint32_t config_header[0x40 >> 2];
uint32_t pcie_pm_cap_base;
uint32_t reserved1[(0x70 - 0x44) >> 2];
uint32_t pcie_cap_base;
uint32_t pcie_dev_cap_base;
uint32_t pcie_dev_ctrl_status;
uint32_t pcie_link_cap_base;
uint32_t reserved2[(0xB0 - 0x80) >> 2];
uint32_t msix_cap_base;
uint32_t reserved3[(0x100 - 0xB4) >> 2];
struct al_pcie_core_aer_regs aer;
uint32_t reserved4[(0x150 -
(0x100 +
sizeof(struct al_pcie_core_aer_regs))) >> 2];
uint32_t pcie_sec_ext_cap_base;
uint32_t reserved5[(0x700 - 0x154) >> 2];
struct al_pcie_core_port_regs port_regs;
uint32_t reserved6[(0x1000 -
(0x700 +
sizeof(struct al_pcie_core_port_regs))) >> 2];
};
struct al_pcie_core_reg_space_rev_3 {
uint32_t config_header[0x40 >> 2];
uint32_t pcie_pm_cap_base;
uint32_t reserved1[(0x70 - 0x44) >> 2];
uint32_t pcie_cap_base;
uint32_t pcie_dev_cap_base;
uint32_t pcie_dev_ctrl_status;
uint32_t pcie_link_cap_base;
uint32_t reserved2[(0xB0 - 0x80) >> 2];
uint32_t msix_cap_base;
uint32_t reserved3[(0x100 - 0xB4) >> 2];
struct al_pcie_core_aer_regs aer;
uint32_t reserved4[(0x158 -
(0x100 +
sizeof(struct al_pcie_core_aer_regs))) >> 2];
/* pcie_sec_cap is only applicable for function 0 */
uint32_t pcie_sec_ext_cap_base;
uint32_t reserved5[(0x178 - 0x15C) >> 2];
/* tph capability is only applicable for rev3 */
uint32_t tph_cap_base;
uint32_t reserved6[(0x700 - 0x17C) >> 2];
/* port_regs is only applicable for function 0 */
struct al_pcie_core_port_regs port_regs;
uint32_t reserved7[(0x1000 -
(0x700 +
sizeof(struct al_pcie_core_port_regs))) >> 2];
};
struct al_pcie_rev3_core_reg_space {
struct al_pcie_core_reg_space_rev_3 func[REV3_MAX_NUM_OF_PFS];
};
struct al_pcie_core_reg_space {
uint32_t *config_header;
uint32_t *pcie_pm_cap_base;
uint32_t *pcie_cap_base;
uint32_t *pcie_dev_cap_base;
uint32_t *pcie_dev_ctrl_status;
uint32_t *pcie_link_cap_base;
uint32_t *msix_cap_base;
struct al_pcie_core_aer_regs *aer;
uint32_t *pcie_sec_ext_cap_base;
uint32_t *tph_cap_base;
};
struct al_pcie_revx_regs {
struct al_pcie_revx_axi_regs __iomem axi;
};
struct al_pcie_rev1_regs {
struct al_pcie_rev1_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev1_axi_regs))) >> 2];
struct al_pcie_rev1_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_1_2_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev1_w_regs))) >> 2];
struct al_pcie_core_reg_space_rev_1_2 core_space;
};
struct al_pcie_rev2_regs {
struct al_pcie_rev2_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev2_axi_regs))) >> 2];
struct al_pcie_rev2_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_1_2_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev2_w_regs))) >> 2];
struct al_pcie_core_reg_space_rev_1_2 core_space;
};
struct al_pcie_rev3_regs {
struct al_pcie_rev3_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_3_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev3_axi_regs))) >> 2];
struct al_pcie_rev3_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_3_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev3_w_regs))) >> 2];
struct al_pcie_rev3_core_reg_space core_space;
};
struct al_pcie_axi_ctrl {
uint32_t *global;
uint32_t *master_arctl;
uint32_t *master_awctl;
uint32_t *slv_ctl;
};
struct al_pcie_axi_ob_ctrl {
uint32_t *cfg_target_bus;
uint32_t *cfg_control;
uint32_t *io_start_l;
uint32_t *io_start_h;
uint32_t *io_limit_l;
uint32_t *io_limit_h;
};
struct al_pcie_axi_pcie_global {
uint32_t *conf;
};
struct al_pcie_axi_conf {
uint32_t *zero_lane0;
uint32_t *zero_lane1;
uint32_t *zero_lane2;
uint32_t *zero_lane3;
uint32_t *zero_lane4;
uint32_t *zero_lane5;
uint32_t *zero_lane6;
uint32_t *zero_lane7;
};
struct al_pcie_axi_status {
uint32_t *lane[AL_MAX_NUM_OF_LANES];
};
struct al_pcie_axi_parity {
uint32_t *en_axi;
};
struct al_pcie_axi_ordering {
uint32_t *pos_cntl;
};
struct al_pcie_axi_pre_configuration {
uint32_t *pcie_core_setup;
};
struct al_pcie_axi_init_fc {
uint32_t *cfg;
};
struct al_pcie_axi_attr_ovrd {
uint32_t *write_msg_ctrl_0;
uint32_t *write_msg_ctrl_1;
uint32_t *pf_sel;
};
struct al_pcie_axi_pf_axi_attr_ovrd {
uint32_t *func_ctrl_0;
uint32_t *func_ctrl_1;
uint32_t *func_ctrl_2;
uint32_t *func_ctrl_3;
uint32_t *func_ctrl_4;
uint32_t *func_ctrl_5;
uint32_t *func_ctrl_6;
uint32_t *func_ctrl_7;
uint32_t *func_ctrl_8;
uint32_t *func_ctrl_9;
};
struct al_pcie_axi_msg_attr_axuser_table {
uint32_t *entry_vec;
};
struct al_pcie_axi_regs {
struct al_pcie_axi_ctrl ctrl;
struct al_pcie_axi_ob_ctrl ob_ctrl;
struct al_pcie_axi_pcie_global pcie_global;
struct al_pcie_axi_conf conf;
struct al_pcie_axi_status status;
struct al_pcie_axi_parity parity;
struct al_pcie_axi_ordering ordering;
struct al_pcie_axi_pre_configuration pre_configuration;
struct al_pcie_axi_init_fc init_fc;
struct al_pcie_revx_axi_int_grp_a_axi *int_grp_a;
/* Rev3 only */
struct al_pcie_axi_attr_ovrd axi_attr_ovrd;
struct al_pcie_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS];
struct al_pcie_axi_msg_attr_axuser_table msg_attr_axuser_table;
};
struct al_pcie_w_global_ctrl {
uint32_t *port_init;
uint32_t *pm_control;
uint32_t *events_gen[REV3_MAX_NUM_OF_PFS];
uint32_t *corr_err_sts_int;
uint32_t *uncorr_err_sts_int;
uint32_t *sris_kp_counter;
};
struct al_pcie_w_soc_int {
uint32_t *mask_inta_leg_0;
uint32_t *mask_inta_leg_3; /* Rev 2/3 only */
uint32_t *mask_msi_leg_0;
uint32_t *mask_msi_leg_3; /* Rev 2/3 only */
};
struct al_pcie_w_atu {
uint32_t *in_mask_pair;
uint32_t *out_mask_pair;
};
struct al_pcie_w_regs {
struct al_pcie_w_global_ctrl global_ctrl;
struct al_pcie_revx_w_debug *debug;
struct al_pcie_revx_w_ap_user_send_msg *ap_user_send_msg;
struct al_pcie_w_soc_int soc_int[REV3_MAX_NUM_OF_PFS];
struct al_pcie_revx_w_cntl_gen *ctrl_gen;
struct al_pcie_revx_w_parity *parity;
struct al_pcie_w_atu atu;
struct al_pcie_revx_w_status_per_func *status_per_func[REV3_MAX_NUM_OF_PFS];
struct al_pcie_revx_w_int_grp *int_grp_a;
struct al_pcie_revx_w_int_grp *int_grp_b;
struct al_pcie_revx_w_int_grp *int_grp_c;
struct al_pcie_revx_w_int_grp *int_grp_d;
};
struct al_pcie_regs {
struct al_pcie_axi_regs axi;
struct al_pcie_w_regs app;
struct al_pcie_core_port_regs *port_regs;
struct al_pcie_core_reg_space core_space[REV3_MAX_NUM_OF_PFS];
};
#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP 0
#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC 4
#define PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE AL_BIT(17)
#define PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT 18
#define PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT 19
#define PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT 20
#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK AL_FIELD_MASK(12, 8)
#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT 8
#define PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT 9
#define PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT 16
#define PCIE_PORT_GEN3_EQ_LF_SHIFT 0
#define PCIE_PORT_GEN3_EQ_LF_MASK 0x3f
#define PCIE_PORT_GEN3_EQ_FS_SHIFT 6
#define PCIE_PORT_GEN3_EQ_FS_MASK (0x3f << PCIE_PORT_GEN3_EQ_FS_SHIFT)
#define PCIE_PORT_LINK_CTRL_LB_EN_SHIFT 2
#define PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT 7
#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK AL_FIELD_MASK(21, 16)
#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT 16
#define PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT 31
#define PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT 0
/** timer_ctrl_max_func_num register
* Max physical function number (for example: 0 for 1PF, 3 for 4PFs)
*/
#define PCIE_PORT_GEN3_MAX_FUNC_NUM AL_FIELD_MASK(7, 0)
/* filter_mask_reg_1 register */
/**
* SKP Interval Value.
* The number of symbol times to wait between transmitting SKP ordered sets
*/
#define PCIE_FLT_MASK_SKP_INT_VAL_MASK AL_FIELD_MASK(10, 0)
/*
* 0: Treat Function MisMatched TLPs as UR
* 1: Treat Function MisMatched TLPs as Supported
*/
#define CX_FLT_MASK_UR_FUNC_MISMATCH AL_BIT(16)
/*
* 0: Treat CFG type1 TLPs as UR for EP; Supported for RC
* 1: Treat CFG type1 TLPs as Supported for EP; UR for RC
*/
#define CX_FLT_MASK_CFG_TYPE1_RE_AS_UR AL_BIT(19)
/*
* 0: Enforce requester id match for received CPL TLPs.
* A violation results in cpl_abort, and possibly AER of unexp_cpl_err,
* cpl_rcvd_ur, cpl_rcvd_ca
* 1: Mask requester id match for received CPL TLPs
*/
#define CX_FLT_MASK_CPL_REQID_MATCH AL_BIT(22)
/*
* 0: Enforce function match for received CPL TLPs.
* A violation results in cpl_abort, and possibly AER of unexp_cpl_err,
* cpl_rcvd_ur, cpl_rcvd_ca
* 1: Mask function match for received CPL TLPs
*/
#define CX_FLT_MASK_CPL_FUNC_MATCH AL_BIT(23)
/* vc0_posted_rcv_q_ctrl register */
#define RADM_PQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_PQ_HCRD_VC0_SHIFT 12
/* vc0_non_posted_rcv_q_ctrl register */
#define RADM_NPQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_NPQ_HCRD_VC0_SHIFT 12
/* vc0_comp_rcv_q_ctrl register */
#define RADM_CPLQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_CPLQ_HCRD_VC0_SHIFT 12
/**** iATU, Control Register 1 ****/
/**
* When the Address and BAR matching logic in the core indicate that a MEM-I/O
* transaction matches a BAR in the function corresponding to this value, then
* address translation proceeds. This check is only performed if the "Function
* Number Match Enable" bit of the "iATU Control 2 Register" is set
*/
#define PCIE_IATU_CR1_FUNC_NUM_MASK AL_FIELD_MASK(24, 20)
#define PCIE_IATU_CR1_FUNC_NUM_SHIFT 20
/**** iATU, Control Register 2 ****/
/** For outbound regions, the Function Number Translation Bypass mode enables
* taking the function number of the translated TLP from the PCIe core
* interface and not from the "Function Number" field of CR1.
* For inbound regions, this bit should be asserted when physical function
* match mode needs to be enabled
*/
#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK AL_BIT(19)
#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT 19
/* pcie_dev_ctrl_status register */
#define PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN AL_BIT(0)
#define PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN AL_BIT(1)
#define PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN AL_BIT(2)
#define PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN AL_BIT(3)
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK AL_FIELD_MASK(7, 5)
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT 5
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT)
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK AL_FIELD_MASK(14, 12)
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT 12
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT)
/******************************************************************************
* AER registers
******************************************************************************/
/* PCI Express Extended Capability ID */
#define PCIE_AER_CAP_ID_MASK AL_FIELD_MASK(15, 0)
#define PCIE_AER_CAP_ID_SHIFT 0
#define PCIE_AER_CAP_ID_VAL 1
/* Capability Version */
#define PCIE_AER_CAP_VER_MASK AL_FIELD_MASK(19, 16)
#define PCIE_AER_CAP_VER_SHIFT 16
#define PCIE_AER_CAP_VER_VAL 2
/* First Error Pointer */
#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_MASK AL_FIELD_MASK(4, 0)
#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_SHIFT 0
/* ECRC Generation Capability */
#define PCIE_AER_CTRL_STAT_ECRC_GEN_SUPPORTED AL_BIT(5)
/* ECRC Generation Enable */
#define PCIE_AER_CTRL_STAT_ECRC_GEN_EN AL_BIT(6)
/* ECRC Check Capable */
#define PCIE_AER_CTRL_STAT_ECRC_CHK_SUPPORTED AL_BIT(7)
/* ECRC Check Enable */
#define PCIE_AER_CTRL_STAT_ECRC_CHK_EN AL_BIT(8)
/* Correctable Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_CORR_ERR_RPRT_EN AL_BIT(0)
/* Non-Fatal Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_NON_FTL_ERR_RPRT_EN AL_BIT(1)
/* Fatal Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_FTL_ERR_RPRT_EN AL_BIT(2)
/* ERR_COR Received */
#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR AL_BIT(0)
/* Multiple ERR_COR Received */
#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR_MULTI AL_BIT(1)
/* ERR_FATAL/NONFATAL Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR AL_BIT(2)
/* Multiple ERR_FATAL/NONFATAL Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR_MULTI AL_BIT(3)
/* First Uncorrectable Fatal */
#define PCIE_AER_ROOT_ERR_STAT_FIRST_UNCORR_FTL AL_BIT(4)
/* Non-Fatal Error Messages Received */
#define PCIE_AER_ROOT_ERR_STAT_NON_FTL_RCVD AL_BIT(5)
/* Fatal Error Messages Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_RCVD AL_BIT(6)
/* Advanced Error Interrupt Message Number */
#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_MASK AL_FIELD_MASK(31, 27)
#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_SHIFT 27
/* ERR_COR Source Identification */
#define PCIE_AER_SRC_ID_CORR_ERR_MASK AL_FIELD_MASK(15, 0)
#define PCIE_AER_SRC_ID_CORR_ERR_SHIFT 0
/* ERR_FATAL/NONFATAL Source Identification */
#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_MASK AL_FIELD_MASK(31, 16)
#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_SHIFT 16
/* AER message */
#define PCIE_AER_MSG_REQID_MASK AL_FIELD_MASK(31, 16)
#define PCIE_AER_MSG_REQID_SHIFT 16
#define PCIE_AER_MSG_TYPE_MASK AL_FIELD_MASK(15, 8)
#define PCIE_AER_MSG_TYPE_SHIFT 8
#define PCIE_AER_MSG_RESERVED AL_FIELD_MASK(7, 1)
#define PCIE_AER_MSG_VALID AL_BIT(0)
/* AER message ack */
#define PCIE_AER_MSG_ACK AL_BIT(0)
/* AER errors definitions */
#define AL_PCIE_AER_TYPE_CORR (0x30)
#define AL_PCIE_AER_TYPE_NON_FATAL (0x31)
#define AL_PCIE_AER_TYPE_FATAL (0x33)
/* Requester ID Bus */
#define AL_PCIE_REQID_BUS_NUM_SHIFT (8)
/******************************************************************************
* TPH registers
******************************************************************************/
#define PCIE_TPH_NEXT_POINTER AL_FIELD_MASK(31, 20)
/******************************************************************************
* Config Header registers
******************************************************************************/
/**
* see BIST_HEADER_TYPE_LATENCY_CACHE_LINE_SIZE_REG in core spec
* Note: valid only for EP mode
*/
#define PCIE_BIST_HEADER_TYPE_BASE 0xc
#define PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK AL_BIT(23)
/******************************************************************************
* SRIS KP counters default values
******************************************************************************/
#define PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL (0x24)
#define PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL (0x4B)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,419 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_services Platform Services API
* @{
* The Platform Services API provides miscellaneous system services to HAL
* drivers, such as:
* - Registers read/write
* - Assertions
* - Memory barriers
* - Endianness conversions
*
* And more.
* @file plat_api/sample/al_hal_plat_services.h
*
* @brief API for Platform services provided for to HAL drivers
*
*
*/
#ifndef __PLAT_SERVICES_H__
#define __PLAT_SERVICES_H__
#include <machine/atomic.h>
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/lock.h>
#include <sys/mutex.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(generic);
bs_protos(generic_armv4);
#define __UNUSED __attribute__((unused))
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/*
* WMA: This is a hack which allows not modifying the __iomem accessing HAL code.
* On ARMv7, bus_handle holds the information about VA of accessed memory. It
* is possible to use direct load/store instruction instead of bus_dma machinery.
* WARNING: This is not guaranteed to stay that way forever, nor that
* on other architectures these variables behave similarly. Keep that
* in mind during porting to other systems.
*/
/**
* Read MMIO 8 bits register
* @param offset register offset
*
* @return register value
*/
static uint8_t al_reg_read8(uint8_t * offset);
/**
* Read MMIO 16 bits register
* @param offset register offset
*
* @return register value
*/
static uint16_t al_reg_read16(uint16_t * offset);
/**
* Read MMIO 32 bits register
* @param offset register offset
*
* @return register value
*/
static uint32_t al_reg_read32(uint32_t * offset);
/**
* Read MMIO 64 bits register
* @param offset register offset
*
* @return register value
*/
uint64_t al_reg_read64(uint64_t * offset);
/**
* Relaxed read MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
*
* @return register value
*/
#define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle)
/**
* Relaxed read MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
*
* @return register value
*/
#define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)
/**
* Relaxed write to MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v)
/**
* Write to MMIO 8 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 16 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 32 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 64 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
static inline uint8_t
al_reg_read8(uint8_t *l)
{
dsb();
return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
}
static inline uint16_t
al_reg_read16(uint16_t *l)
{
dsb();
return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
}
static inline uint32_t
al_reg_read32(uint32_t *l)
{
dsb();
return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
}
#define AL_DBG_LEVEL_NONE 0
#define AL_DBG_LEVEL_ERR 1
#define AL_DBG_LEVEL_WARN 2
#define AL_DBG_LEVEL_INFO 3
#define AL_DBG_LEVEL_DBG 4
#define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
extern struct mtx al_dbg_lock;
#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock)
#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock)
/**
* print message
*
* @param format The format string
* @param ... Additional arguments
*/
#define al_print(type, fmt, ...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_NONE) { AL_DBG_LOCK(); printf(fmt, ##__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print error message
*
* @param format
*/
#define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print warning message
*
* @param format
*/
#define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print info message
*
* @param format
*/
#define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print debug message
*
* @param format
*/
#define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* Assertion
*
* @param condition
*/
#define al_assert(COND) \
do { \
if (!(COND)) \
al_err( \
"%s:%d:%s: Assertion failed! (%s)\n", \
__FILE__, __LINE__, __func__, #COND); \
} while(AL_FALSE)
/**
* Make sure data will be visible by other masters (other CPUS and DMA).
* usually this is achieved by the ARM DMB instruction.
*/
static void al_data_memory_barrier(void);
/**
* Make sure data will be visible by DMA masters, no restriction for other cpus
*/
static inline void
al_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure data will be visible in order by other cpus masters.
*/
static inline void
al_smp_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure write data will be visible in order by other cpus masters.
*/
static inline void
al_local_data_memory_barrier(void)
{
dsb();
}
/**
* al_udelay - micro sec delay
*/
#define al_udelay(u) DELAY(u)
/**
* al_msleep - mili sec delay
*/
#define al_msleep(m) DELAY((m) * 1000)
/**
* swap half word to little endian
*
* @param x 16 bit value
*
* @return the value in little endian
*/
#define swap16_to_le(x) htole16(x)
/**
* swap word to little endian
*
* @param x 32 bit value
*
* @return the value in little endian
*/
#define swap32_to_le(x) htole32(x)
/**
* swap 8 bytes to little endian
*
* @param x 64 bit value
*
* @return the value in little endian
*/
#define swap64_to_le(x) htole64(x)
/**
* swap half word from little endian
*
* @param x 16 bit value
*
* @return the value in the cpu endianess
*/
#define swap16_from_le(x) le16toh(x)
/**
* swap word from little endian
*
* @param x 32 bit value
*
* @return the value in the cpu endianess
*/
#define swap32_from_le(x) le32toh(x)
/**
* swap 8 bytes from little endian
*
* @param x 64 bit value
*
* @return the value in the cpu endianess
*/
#define swap64_from_le(x) le64toh(x)
/**
* Memory set
*
* @param p memory pointer
* @param val value for setting
* @param cnt number of bytes to set
*/
#define al_memset(p, val, cnt) memset(p, val, cnt)
/**
* Memory copy
*
* @param p1 memory pointer
* @param p2 memory pointer
* @param cnt number of bytes to copy
*/
#define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt)
/**
* Memory compare
*
* @param p1 memory pointer
* @param p2 memory pointer
* @param cnt number of bytes to compare
*/
#define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt)
/**
* String compare
*
* @param s1 string pointer
* @param s2 string pointer
*/
#define al_strcmp(s1, s2) strcmp(s1, s2)
#define al_get_cpu_id() 0
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Platform Services API group */
#endif /* __PLAT_SERVICES_H__ */

View File

@ -0,0 +1,94 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_services Platform Services API
* @{
* @file plat_api/sample/al_hal_plat_types.h
*
*/
#ifndef __PLAT_TYPES_H__
#define __PLAT_TYPES_H__
#include <sys/cdefs.h>
#include <sys/param.h>
#include <machine/bus.h>
#include <sys/bus.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* Basic data types */
typedef int al_bool; /** boolean */
#define AL_TRUE 1
#define AL_FALSE 0
/* define types */
#ifndef AL_HAVE_TYPES
typedef unsigned char uint8_t; /** unsigned 8 bits */
typedef unsigned short uint16_t; /** unsigned 16 bits */
typedef unsigned int uint32_t; /** unsigned 32 bits */
typedef unsigned long long uint64_t; /** unsigned 64 bits */
typedef signed char int8_t; /** signed 8 bits */
typedef short int int16_t; /** signed 16 bits */
typedef signed int int32_t; /** signed 32 bits */
/** An unsigned int that is guaranteed to be the same size as a pointer */
/** C99 standard */
typedef unsigned long uintptr_t;
#endif
/** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */
typedef uint64_t al_phys_addr_t;
/** this defines the cpu endiancess. */
#define PLAT_ARCH_IS_LITTLE() AL_TRUE
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Platform Services API group */
#endif /* __PLAT_TYPES_H__ */

View File

@ -0,0 +1,188 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* @{
* @file al_hal_reg_utils.h
*
* @brief Register utilities used by HALs and platform layer
*
*
*/
#ifndef __AL_HAL_REG_UTILS_H__
#define __AL_HAL_REG_UTILS_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#define AL_BIT(b) (1UL << (b))
#define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x)))
#define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16))
/** get field out of 32 bit register */
#define AL_REG_FIELD_GET(reg, mask, shift) (((reg) & (mask)) >> (shift))
/** set field of 32 bit register */
#define AL_REG_FIELD_SET(reg, mask, shift, val) \
(reg) = \
(((reg) & (~(mask))) | \
((((unsigned)(val)) << (shift)) & (mask)))
/** set field of 64 bit register */
#define AL_REG_FIELD_SET_64(reg, mask, shift, val) \
((reg) = \
(((reg) & (~(mask))) | \
((((uint64_t)(val)) << (shift)) & (mask))))
/** get single bit out of 32 bit register */
#define AL_REG_BIT_GET(reg, shift) \
AL_REG_FIELD_GET(reg, AL_BIT(shift), shift)
#define AL_REG_BITS_FIELD(shift, val) \
(((unsigned)(val)) << (shift))
/** set single bit field of 32 bit register to a given value */
#define AL_REG_BIT_VAL_SET(reg, shift, val) \
AL_REG_FIELD_SET(reg, AL_BIT(shift), shift, val)
/** set single bit of 32 bit register to 1 */
#define AL_REG_BIT_SET(reg, shift) \
AL_REG_BIT_VAL_SET(reg, shift, 1)
/** clear single bit of 32 bit register */
#define AL_REG_BIT_CLEAR(reg, shift) \
AL_REG_BIT_VAL_SET(reg, shift, 0)
#define AL_BIT_MASK(n) \
(AL_BIT(n) - 1)
#define AL_FIELD_MASK(msb, lsb) \
(AL_BIT(msb) + AL_BIT_MASK(msb) - AL_BIT_MASK(lsb))
/** clear bits specified by clear_mask */
#define AL_REG_MASK_CLEAR(reg, clear_mask) \
((reg) = (((reg) & (~(clear_mask)))))
/** set bits specified by clear_mask */
#define AL_REG_MASK_SET(reg, clear_mask) \
((reg) = (((reg) | (clear_mask))))
/** clear bits specified by clear_mask, and set bits specified by set_mask */
#define AL_REG_CLEAR_AND_SET(reg, clear_mask, set_mask) \
(reg) = (((reg) & (~(clear_mask))) | (set_mask))
#define AL_ALIGN_UP(val, size) \
((size) * (((val) + (size) - 1) / (size)))
/** take bits selected by mask from one data, the rest from background */
#define AL_MASK_VAL(mask, data, background) \
(((mask) & (data)) | ((~mask) & (background)))
/**
* 8 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write8_masked(uint8_t __iomem *reg, uint8_t mask, uint8_t data)
{
uint8_t temp;
temp = al_reg_read8(reg);
al_reg_write8(reg, AL_MASK_VAL(mask, data, temp));
}
/**
* 16 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write16_masked(uint16_t __iomem *reg, uint16_t mask, uint16_t data)
{
uint16_t temp;
temp = al_reg_read16(reg);
al_reg_write16(reg, AL_MASK_VAL(mask, data, temp));
}
/**
* 32 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write32_masked(uint32_t __iomem *reg, uint32_t mask, uint32_t data)
{
uint32_t temp;
temp = al_reg_read32(reg);
al_reg_write32(reg, AL_MASK_VAL(mask, data, temp));
}
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Common group */
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes_25g.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_25G_H__
#define __AL_HAL_SERDES_25G_H__
#include "al_hal_common.h"
#include "al_hal_serdes_interface.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
int al_serdes_25g_handle_init(
void __iomem *serdes_regs_base,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_SRDS__ */
/** @} end of SERDES group */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,434 @@
/*******************************************************************************
Copyright (C) 2013 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 or V3 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_serdes_c_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_serdes_c_REGS_H__
#define __AL_HAL_serdes_c_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct al_serdes_c_gen {
/* [0x0] SERDES registers Version */
uint32_t version;
uint32_t rsrvd_0[3];
/* [0x10] SERDES register file address */
uint32_t reg_addr;
/* [0x14] SERDES register file data */
uint32_t reg_data;
/* [0x18] SERDES control */
uint32_t ctrl;
/* [0x1c] SERDES cpu mem address */
uint32_t cpu_prog_addr;
/* [0x20] SERDES cpu mem data */
uint32_t cpu_prog_data;
/* [0x24] SERDES data mem address */
uint32_t cpu_data_mem_addr;
/* [0x28] SERDES data mem data */
uint32_t cpu_data_mem_data;
/* [0x2c] SERDES control */
uint32_t rst;
/* [0x30] SERDES control */
uint32_t status;
uint32_t rsrvd[51];
};
struct al_serdes_c_lane {
uint32_t rsrvd_0[4];
/* [0x10] Data configuration */
uint32_t cfg;
/* [0x14] Lane status */
uint32_t stat;
/* [0x18] SERDES control */
uint32_t reserved;
uint32_t rsrvd[25];
};
struct al_serdes_c_regs {
uint32_t rsrvd_0[64];
struct al_serdes_c_gen gen; /* [0x100] */
struct al_serdes_c_lane lane[2]; /* [0x200] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define SERDES_C_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* date of release */
#define SERDES_C_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define SERDES_C_GEN_VERSION_DATE_DAY_SHIFT 16
/* month of release */
#define SERDES_C_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define SERDES_C_GEN_VERSION_DATA_MONTH_SHIFT 21
/* year of release (starting from 2000) */
#define SERDES_C_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define SERDES_C_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define SERDES_C_GEN_VERSION_RESERVED_MASK 0xC0000000
#define SERDES_C_GEN_VERSION_RESERVED_SHIFT 30
/**** reg_addr register ****/
/* address value */
#define SERDES_C_GEN_REG_ADDR_VAL_MASK 0x00007FFF
#define SERDES_C_GEN_REG_ADDR_VAL_SHIFT 0
/**** reg_data register ****/
/* data value */
#define SERDES_C_GEN_REG_DATA_VAL_MASK 0x000000FF
#define SERDES_C_GEN_REG_DATA_VAL_SHIFT 0
/* Bit-wise write enable */
#define SERDES_C_GEN_REG_DATA_STRB_MASK 0x0000FF00
#define SERDES_C_GEN_REG_DATA_STRB_SHIFT 8
/**** ctrl register ****/
/*
* 0x0 Select reference clock from Bump
* 0x1 Select inter-macro reference clock from the left side
* 0x2 Same as 0x0
* 0x3 Select inter-macro reference clock from the right side
*/
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_MASK 0x00000003
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT 0
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_REF \
(0 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_L2R \
(1 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_R2L \
(3 << (SERDES_C_GEN_CTRL_REFCLK_INPUT_SEL_SHIFT))
/*
* 0x0 Tied to 0 to save power
* 0x1 Select reference clock from Bump
* 0x2 Select inter-macro reference clock input from right side
* 0x3 Same as 0x2
*/
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_MASK 0x00000030
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT 4
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_0 \
(0 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_REF \
(1 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_R2L \
(2 << (SERDES_C_GEN_CTRL_REFCLK_LEFT_SEL_SHIFT))
/*
* 0x0 Tied to 0 to save power
* 0x1 Select reference clock from Bump
* 0x2 Select inter-macro reference clock input from left side
* 0x3 Same as 0x2
*/
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_MASK 0x000000C0
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT 6
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_0 \
(0 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_REF \
(1 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
#define SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_L2R \
(2 << (SERDES_C_GEN_CTRL_REFCLK_RIGHT_SEL_SHIFT))
/*
* Program memory acknowledge - Only when the access
* to the program memory is not
* ready for the microcontroller, it
* is driven to 0
*/
#define SERDES_C_GEN_CTRL_CPU_MEMPSACK (1 << 8)
/*
* Data memory acknowledge - Only when the access
* to the program memory is not
* ready for the microcontroller, it
* is driven to 0
*/
#define SERDES_C_GEN_CTRL_CPU_MEMACK (1 << 12)
/*
* 0 - keep cpu clk as sb clk
* 1 cpu_clk is sb_clk divided by 2
*/
#define SERDES_C_GEN_CTRL_CPU_CLK_DIV (1 << 16)
/*
* 0x0 OIF CEI-28G-SR
* 0x1 OIF CIE-25G-LR
* 0x8 XFI
* Others Reserved
*
* Note that phy_ctrl_cfg_i[3] is used to signify high-speed/low-speed
*/
#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_MASK 0x00F00000
#define SERDES_C_GEN_CTRL_PHY_CTRL_CFG_SHIFT 20
/*
* 0 - Internal 8051 micro- controller is allowed to access the internal APB
* CSR. Internal APB runs at cpu_clk_i, and the accesses from the external APB
* in apb_clk_i domain to APB CSR are resynchronized to cpu_clk_i. 1 Bypass
* CPU. Internal 8051 micro-controller is blocked from accessing the internal
* APB CSR. Internal APB runs at apb_clk_i.
*/
#define SERDES_C_GEN_CTRL_CPU_BYPASS (1 << 24)
/**** cpu_prog_addr register ****/
/*
* address value 32 bit,
* The firmware data will be 1 byte with 64K rows
*/
#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_MASK 0x00007FFF
#define SERDES_C_GEN_CPU_PROG_ADDR_VAL_SHIFT 0
/**** cpu_data_mem_addr register ****/
/* address value 8K byte memory */
#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_MASK 0x00001FFF
#define SERDES_C_GEN_CPU_DATA_MEM_ADDR_VAL_SHIFT 0
/**** cpu_data_mem_data register ****/
/* data value */
#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_MASK 0x000000FF
#define SERDES_C_GEN_CPU_DATA_MEM_DATA_VAL_SHIFT 0
/**** rst register ****/
/* Power on reset Signal active low */
#define SERDES_C_GEN_RST_POR_N (1 << 0)
/* CMU reset Active low */
#define SERDES_C_GEN_RST_CM0_RST_N (1 << 1)
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Near complete power down (only
* refclk buffers and portions of analog bias
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when CMU is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* effect in power on reset state.
*/
#define SERDES_C_GEN_RST_CM0_PD_MASK 0x00000030
#define SERDES_C_GEN_RST_CM0_PD_SHIFT 4
/* Lane0 reset signal active low */
#define SERDES_C_GEN_RST_LN0_RST_N (1 << 6)
/* Lane1 reset signal active low */
#define SERDES_C_GEN_RST_LN1_RST_N (1 << 7)
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Most blocks powered down (only LOS
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when Lane is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* affect in power on reset state
*/
#define SERDES_C_GEN_RST_LN0_PD_MASK 0x00000300
#define SERDES_C_GEN_RST_LN0_PD_SHIFT 8
/*
* 0x0 Normal / Active
* 0x1 Partial power down
* 0x2 Most blocks powered down (only LOS
* active)
* 0x3 complete power down (IDDQ mode)
* Can be asserted when Lane is in normal
* mode. These modes provide an increased
* power savings compared to reset mode.
* Signal is overridden by por_n_i so has no
* affect in power on reset state
*/
#define SERDES_C_GEN_RST_LN1_PD_MASK 0x00000C00
#define SERDES_C_GEN_RST_LN1_PD_SHIFT 10
#define SERDES_C_GEN_RST_CPU_MEM_RESET (1 << 12)
#define SERDES_C_GEN_RST_CPU_MEM_SHUTDOWN (1 << 13)
#define SERDES_C_GEN_RST_CAPRI_APB_RESET (1 << 14)
/**** status register ****/
/*
* 0x0 No error
* 0x1 PHY has an internal error
*/
#define SERDES_C_GEN_STATUS_ERR_O (1 << 0)
/*
* 0x0 PHY is not ready to respond to
* cm0_rst_n_i and cm0_pd_i[1:0]. The
* signals should not be changed.
* 0x1 - PHY is ready to respond to
* cm0_rst_n_i and cm0_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_CM0_RST_PD_READY (1 << 1)
/*
* Indicates CMU PLL has locked to the
* reference clock and all output clocks are at
* the correct frequency
*/
#define SERDES_C_GEN_STATUS_CM0_OK_O (1 << 2)
/*
* 0x0 PHY is not ready to respond to
* ln0_rst_n and ln0_pd[1:0]. The signals
* should not be changed.
* 0x1 - PHY is ready to respond to lnX_rst_n_i
* and lnX_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_LN0_RST_PD_READY (1 << 3)
/*
* 0x0 PHY is not ready to respond to
* ln1_rst_n_i and ln1_pd[1:0]. The signals
* should not be changed.
* 0x1 - PHY is ready to respond to lnX_rst_n_i
* and lnX_pd_i[1:0]
*/
#define SERDES_C_GEN_STATUS_LN1_RST_PD_READY (1 << 4)
/*
* Active low when the CPU performs a wait cycle (internally or externally
* generated)
*/
#define SERDES_C_GEN_STATUS_CPU_WAITSTATE (1 << 5)
#define SERDES_C_GEN_STATUS_TBUS_MASK 0x000FFF00
#define SERDES_C_GEN_STATUS_TBUS_SHIFT 8
/**** cfg register ****/
/* 1- Swap 32 bit data on RX side */
#define SERDES_C_LANE_CFG_RX_LANE_SWAP (1 << 0)
/* 1- Swap 32 bit data on TX side */
#define SERDES_C_LANE_CFG_TX_LANE_SWAP (1 << 1)
/* 1 invert rx data polarity */
#define SERDES_C_LANE_CFG_LN_CTRL_RXPOLARITY (1 << 2)
/* 1 invert tx data polarity */
#define SERDES_C_LANE_CFG_TX_LANE_POLARITY (1 << 3)
/*
* 0x0 Data on lnX_txdata_o will not be
* transmitted. Transmitter will be placed into
* electrical idle.
* 0x1 Data on the active bits of
* lnX_txdata_o will be transmitted
*/
#define SERDES_C_LANE_CFG_LN_CTRL_TX_EN (1 << 4)
/*
* Informs the PHY to bypass the output of the
* analog LOS detector and instead rely upon
* a protocol LOS mechanism in the SoC/ASIC
* 0x0 LOS operates as normal
* 0x1 Bypass analog LOS output and
* instead rely upon protocol-level LOS
* detection via input lnX_ctrl_los_eii_value
*/
#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_EN (1 << 5)
/*
* If lnX_ctrl_los_eii_en_i = 1 then Informs
* the PHY that the received signal was lost
*/
#define SERDES_C_LANE_CFG_LN_CTRL_LOS_EII_VALUE (1 << 6)
/* One hot mux */
#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_MASK 0x00000F00
#define SERDES_C_LANE_CFG_TX_DATA_SRC_SELECT_SHIFT 8
/* 0x0 - 20-bit 0x1 40-bit */
#define SERDES_C_LANE_CFG_LN_CTRL_DATA_WIDTH (1 << 12)
/**** stat register ****/
/*
* x0 lane is not ready to send and receive data
* 0x1 lane is ready to send and receive data
*/
#define SERDES_C_LANE_STAT_LNX_STAT_OK (1 << 0)
/*
* 0x0 received data run length has not
* exceed the programmable run length
* detector threshold
* 0x1 received data run length has
* exceeded the programmable run length
* detector threshold
*/
#define SERDES_C_LANE_STAT_LN_STAT_RUNLEN_ERR (1 << 1)
/*
* 0x0 data on lnX_rxdata_o are invalid
* 0x1 data on the active bits of
* lnX_rxdata_o are valid
*/
#define SERDES_C_LANE_STAT_LN_STAT_RXVALID (1 << 2)
/*
* Loss of Signal (LOS) indicator that includes
* the combined functions of the digitally
* assisted analog LOS, digital LOS, and
* protocol LOS override features
* 0x0 Signal detected on lnX_rxp_i /
* lnX_rxm_i pins
* 0x1 No signal detected on lnX_rxp_i /
* lnX_rxm_i pins
*/
#define SERDES_C_LANE_STAT_LN_STAT_LOS (1 << 3)
#define SERDES_C_LANE_STAT_LN_STAT_LOS_DEGLITCH (1 << 4)
/**** reserved register ****/
#define SERDES_C_LANE_RESERVED_DEF_0_MASK 0x0000FFFF
#define SERDES_C_LANE_RESERVED_DEF_0_SHIFT 0
#define SERDES_C_LANE_RESERVED_DEF_1_MASK 0xFFFF0000
#define SERDES_C_LANE_RESERVED_DEF_1_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_serdes_c_REGS_H__ */
/** @} end of ... group */

View File

@ -0,0 +1,87 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_H__
#define __AL_HAL_SERDES_H__
#include "al_hal_common.h"
#include "al_hal_serdes_interface.h"
#include "al_hal_serdes_hssp_regs.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* Initializes a SERDES group object
*
* @param serdes_regs_base
* The SERDES register file base pointer
*
* @param obj
* An allocated, non initialized object context
*
* @return 0 if no error found.
*
*/
int al_serdes_hssp_handle_init(
void __iomem *serdes_regs_base,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_SRDS__ */
/** @} end of SERDES group */

View File

@ -0,0 +1,749 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_SERDES_INTERNAL_REGS_H__
#define __AL_SERDES_INTERNAL_REGS_H__
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Per lane register fields
******************************************************************************/
/*
* RX and TX lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT 0x01
/*
* RX and TX lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS 0x02
/* RX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM 3
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0 0x10
/* TX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM 4
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0 0x10
/* RX lane word width */
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_10 0x01
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_16 0x02
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 0x03
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_32 0x04
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_40 0x05
/* TX lane word width */
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_10 0x10
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_16 0x20
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20 0x30
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_32 0x40
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_40 0x50
/* RX lane rate select */
#define SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSRX_DIVRATE_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4 0x01
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2 0x02
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1 0x03
/* TX lane rate select */
#define SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSTX_DIVRATE_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4 0x10
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2 0x20
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1 0x30
/*
* PMA serial RX-to-TX loop-back enable (from AGC to IO Driver). Serial receive
* to transmit loopback: 0 - Disables loopback 1 - Transmits the untimed,
* partial equalized RX signal out the transmit IO pins
*/
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN 0x10
/*
* PMA TX-to-RX buffered serial loop-back enable (bypasses IO Driver). Serial
* transmit to receive buffered loopback: 0 - Disables loopback 1 - Loops back
* the TX serializer output into the CDR
*/
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN 0x20
/*
* PMA TX-to-RX I/O serial loop-back enable (loop back done directly from TX to
* RX pads). Serial IO loopback from the transmit lane IO pins to the receive
* lane IO pins: 0 - Disables loopback 1 - Loops back the driver IO signal to
* the RX IO pins
*/
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN 0x40
/*
* PMA Parallel RX-to-TX loop-back enable. Parallel loopback from the PMA
* receive lane 20-bit data ports, to the transmit lane 20-bit data ports 0 -
* Disables loopback 1 - Loops back the 20-bit receive data port to the
* transmitter
*/
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN 0x80
/*
* PMA CDR recovered-clock loopback enable; asserted when PARRX2TXTIMEDEN is 1.
* Transmit bit clock select: 0 - Selects synthesizer bit clock for transmit 1
* - Selects CDR clock for transmit
*/
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN 0x01
/* Receive lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSRXBIST_EN 0x01
/* TX lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSTXBIST_EN 0x02
/*
* RX BIST completion signal 0 - Indicates test is not completed 1 - Indicates
* the test has completed, and will remain high until a new test is initiated
*/
#define SERDES_IREG_FLD_RXBIST_DONE_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_DONE 0x04
/*
* RX BIST error count overflow indicator. Indicates an overflow in the number
* of byte errors identified during the course of the test. This word is stable
* to sample when *_DONE_* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW 0x08
/*
* RX BIST locked indicator 0 - Indicates BIST is not word locked and error
* comparisons have not begun yet 1 - Indicates BIST is word locked and error
* comparisons have begun
*/
#define SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_RXLOCKED 0x10
/*
* RX BIST error count word. Indicates the number of byte errors identified
* during the course of the test. This word is stable to sample when *_DONE_*
* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM 9
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM 10
/* Tx params */
#define SERDES_IREG_TX_DRV_1_REG_NUM 21
#define SERDES_IREG_TX_DRV_1_HLEV_MASK 0x7
#define SERDES_IREG_TX_DRV_1_HLEV_SHIFT 0
#define SERDES_IREG_TX_DRV_1_LEVN_MASK 0xf8
#define SERDES_IREG_TX_DRV_1_LEVN_SHIFT 3
#define SERDES_IREG_TX_DRV_2_REG_NUM 22
#define SERDES_IREG_TX_DRV_2_LEVNM1_MASK 0xf
#define SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT 0
#define SERDES_IREG_TX_DRV_2_LEVNM2_MASK 0x30
#define SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT 4
#define SERDES_IREG_TX_DRV_3_REG_NUM 23
#define SERDES_IREG_TX_DRV_3_LEVNP1_MASK 0x7
#define SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT 0
#define SERDES_IREG_TX_DRV_3_SLEW_MASK 0x18
#define SERDES_IREG_TX_DRV_3_SLEW_SHIFT 3
/* Rx params */
#define SERDES_IREG_RX_CALEQ_1_REG_NUM 24
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT 0
/* DFE post-shaping tap 3dB frequency */
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK 0x38
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT 3
#define SERDES_IREG_RX_CALEQ_2_REG_NUM 25
/* DFE post-shaping tap gain */
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT 0
/* DFE first tap gain control */
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK 0x78
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT 3
#define SERDES_IREG_RX_CALEQ_3_REG_NUM 26
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK 0xf0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_4_REG_NUM 27
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK 0x70
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_5_REG_NUM 28
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK 0x7
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT 0
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK 0xf8
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT 3
/* RX lane best eye point measurement result */
#define SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM 29
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM 30
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK 0x3F
/*
* Adaptive RX Equalization enable
* 0 - Disables adaptive RX equalization.
* 1 - Enables adaptive RX equalization.
*/
#define SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM 31
#define SERDES_IREG_FLD_PCSRXEQ_START (1 << 0)
/*
* Enables an eye diagram measurement
* within the PHY.
* 0 - Disables eye diagram measurement
* 1 - Enables eye diagram measurement
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM 31
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START (1 << 1)
/*
* RX lane single roam eye point measurement start signal.
* If asserted, single measurement at fix XADJUST and YADJUST is started.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM 31
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START (1 << 2)
/*
* PHY Eye diagram measurement status
* signal
* 0 - Indicates eye diagram results are not
* valid for sampling
* 1 - Indicates eye diagram is complete and
* results are valid for sampling
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE (1 << 0)
/*
* Eye diagram error signal. Indicates if the
* measurement was invalid because the eye
* diagram was interrupted by the link entering
* electrical idle.
* 0 - Indicates eye diagram is valid
* 1- Indicates an error occurred, and the eye
* diagram measurement should be re-run
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR (1 << 1)
/*
* PHY Adaptive Equalization status
* 0 - Indicates Adaptive Equalization results are not valid for sampling
* 1 - Indicates Adaptive Equalization is complete and results are valid for
* sampling
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE (1 << 2)
/*
*
* PHY Adaptive Equalization Status Signal
* 0 Indicates adaptive equalization results
* are not valid for sampling
* 1 Indicates adaptive equalization is
* complete and results are valid for sampling.
*/
#define SERDES_IREG_FLD_RXEQ_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_DONE (1 << 3)
/*
* 7-bit eye diagram time adjust control
* - 6-bits per UI
* - spans 2 UI
*/
#define SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM 33
/* 6-bit eye diagram voltage adjust control - spans +/-300mVdiff */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM 34
/*
* Eye diagram status signal. Safe for
* sampling when *DONE* signal has
* asserted
* 14'h0000 - Completely Closed Eye
* 14'hFFFF - Completely Open Eye
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM 35
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_MAKE 0xFF
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM 36
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE 0x3F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_SHIFT 0
/*
* RX lane single roam eye point measurement result.
* If 0, eye is open at current XADJUST and YADJUST settings.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM 37
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM 38
/*
* Override enable for CDR lock to reference clock
* 0 - CDR is always locked to reference
* 1 - CDR operation mode (Lock2Reference or Lock2data are controlled internally
* depending on the incoming signal and ppm status)
*/
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM 39
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN (1 << 1)
/*
* Selects Eye to capture based on edge
* 0 - Capture 1st Eye in Eye Diagram
* 1 - Capture 2nd Eye in Eye Diagram measurement
*/
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM 39
#define SERDES_IREG_FLD_RXROAM_XORBITSEL (1 << 2)
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_1ST 0
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND (1 << 2)
/*
* RX Signal detect. 0 indicates no signal, 1 indicates signal detected.
*/
#define SERDES_IREG_FLD_RXRANDET_REG_NUM 41
#define SERDES_IREG_FLD_RXRANDET_STAT 0x20
/*
* RX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_RX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_RX_INV (1 << 0)
/*
* TX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_TX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_TX_INV (1 << 1)
/* LANEPCSPSTATE* override enable (Active low) */
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN (1 << 0)
/* LB* override enable (Active low) */
#define SERDES_IREG_FLD_LB_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LB_LOCWREN (1 << 1)
/* PCSRX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRX_LOCWREN (1 << 4)
/* PCSRXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN (1 << 5)
/* PCSRXEQ* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN (1 << 6)
/* PCSTX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSTX_LOCWREN (1 << 7)
/*
* group registers:
* SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN,
* SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN
* SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN
*/
#define SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM 86
/* PCSTXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN (1 << 0)
/* Override RX_CALCEQ through the internal registers (Active low) */
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM 86
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN (1 << 3)
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN (1 << 4)
/* RXCALROAMEYEMEASIN* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN (1 << 6)
/* RXCALROAMXADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN (1 << 7)
/* RXCALROAMYADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN (1 << 0)
/* RXCDRCALFOSC* override enable. Active Low */
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN (1 << 1)
/* Over-write enable for RXEYEDIAGFSM_INITXVAL */
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN (1 << 2)
/* Over-write enable for CMNCLKGENMUXSEL_TXINTERNAL */
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN (1 << 3)
/* TXCALTCLKDUTY* override enable. Active Low */
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN (1 << 4)
/* Override TX_DRV through the internal registers (Active low) */
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM 87
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN (1 << 5)
/*******************************************************************************
* Common lane register fields - PMA
******************************************************************************/
/*
* Common lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS 0x01
/*
* Common lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT 0x02
/* Synth power state control */
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM 3
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK 0x1f
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD 0x01
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2 0x02
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1 0x04
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S 0x08
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0 0x10
/* Transmit datapath FIFO enable (Active High) */
#define SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM 8
#define SERDES_IREG_FLD_CMNPCS_TXENABLE (1 << 2)
/*
* RX lost of signal detector enable
* - 0 - disable
* - 1 - enable
*/
#define SERDES_IREG_FLD_RXLOSDET_ENABLE_REG_NUM 13
#define SERDES_IREG_FLD_RXLOSDET_ENABLE AL_BIT(4)
/* Signal Detect Threshold Level */
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_MASK AL_FIELD_MASK(2, 0)
/* LOS Detect Threshold Level */
#define SERDES_IREG_FLD_RXLOSDET_THRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXLOSDET_THRESH_MASK AL_FIELD_MASK(4, 3)
#define SERDES_IREG_FLD_RXLOSDET_THRESH_SHIFT 3
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM 30
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM 31
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM 34
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM 36
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM 37
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM 43
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT 0
#define SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(byte_num) (56 + (byte_num))
#define SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES 10
/*
* Selects the transmit BIST mode:
* 0 - Uses the 80-bit internal memory pattern (w/ OOB)
* 1 - Uses a 27 PRBS pattern
* 2 - Uses a 223 PRBS pattern
* 3 - Uses a 231 PRBS pattern
* 4 - Uses a 1010 clock pattern
* 5 and above - Reserved
*/
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM 80
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK 0x07
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER 0x00
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7 0x01
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23 0x02
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31 0x03
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010 0x04
/* Single-Bit error injection enable (on posedge) */
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM 80
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN 0x20
/* CMNPCIEGEN3* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN (1 << 2)
/* CMNPCS* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCS_LOCWREN (1 << 3)
/* CMNPCSBIST* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN (1 << 4)
/* CMNPCSPSTATE* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN (1 << 5)
/* PCS_EN* override enable (Active Low) */
#define SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM 96
#define SERDES_IREG_FLD_PCS_LOCWREN (1 << 3)
/* Eye diagram sample count */
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM 150
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT 0
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM 151
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT 0
/* override control */
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM 230
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN 1 << 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM 623
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM 624
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT 0
/* X and Y coefficient return value */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM 626
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_MASK 0xF0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_SHIFT 4
/* X coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM 627
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT 0
/* X fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM 628
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT 0
/* Y coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM 629
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT 0
/* Y fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM 630
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT 0
#define SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM 157
#define SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM 158
#define SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM 159
#define SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM 160
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM 163
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM 164
/*******************************************************************************
* Common lane register fields - PCS
******************************************************************************/
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM 3
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK AL_FIELD_MASK(5, 4)
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT 4
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM 6
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA AL_BIT(2)
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM 18
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM 19
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM 20
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM 21
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_REG_NUM 23
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_REG_NUM 24
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_REG_NUM 35
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_MASK 0x1f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_REG_NUM 37
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_MASK 0xe0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_SHIFT 5
#ifdef __cplusplus
}
#endif
#endif /* __AL_serdes_REG_H */

View File

@ -0,0 +1,494 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_serdes_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_SERDES_REGS_H__
#define __AL_HAL_SERDES_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct serdes_gen {
/* [0x0] SerDes Registers Version */
uint32_t version;
uint32_t rsrvd_0[3];
/* [0x10] SerDes register file address */
uint32_t reg_addr;
/* [0x14] SerDes register file data */
uint32_t reg_data;
uint32_t rsrvd_1[2];
/* [0x20] SerDes control */
uint32_t ictl_multi_bist;
/* [0x24] SerDes control */
uint32_t ictl_pcs;
/* [0x28] SerDes control */
uint32_t ictl_pma;
uint32_t rsrvd_2;
/* [0x30] SerDes control */
uint32_t ipd_multi_synth;
/* [0x34] SerDes control */
uint32_t irst;
/* [0x38] SerDes control */
uint32_t octl_multi_synthready;
/* [0x3c] SerDes control */
uint32_t octl_multi_synthstatus;
/* [0x40] SerDes control */
uint32_t clk_out;
uint32_t rsrvd[47];
};
struct serdes_lane {
uint32_t rsrvd1[4];
/* [0x10] SerDes status */
uint32_t octl_pma;
/* [0x14] SerDes control */
uint32_t ictl_multi_andme;
/* [0x18] SerDes control */
uint32_t ictl_multi_lb;
/* [0x1c] SerDes control */
uint32_t ictl_multi_rxbist;
/* [0x20] SerDes control */
uint32_t ictl_multi_txbist;
/* [0x24] SerDes control */
uint32_t ictl_multi;
/* [0x28] SerDes control */
uint32_t ictl_multi_rxeq;
/* [0x2c] SerDes control */
uint32_t ictl_multi_rxeq_l_low;
/* [0x30] SerDes control */
uint32_t ictl_multi_rxeq_l_high;
/* [0x34] SerDes control */
uint32_t ictl_multi_rxeyediag;
/* [0x38] SerDes control */
uint32_t ictl_multi_txdeemph;
/* [0x3c] SerDes control */
uint32_t ictl_multi_txmargin;
/* [0x40] SerDes control */
uint32_t ictl_multi_txswing;
/* [0x44] SerDes control */
uint32_t idat_multi;
/* [0x48] SerDes control */
uint32_t ipd_multi;
/* [0x4c] SerDes control */
uint32_t octl_multi_rxbist;
/* [0x50] SerDes control */
uint32_t octl_multi;
/* [0x54] SerDes control */
uint32_t octl_multi_rxeyediag;
/* [0x58] SerDes control */
uint32_t odat_multi_rxbist;
/* [0x5c] SerDes control */
uint32_t odat_multi_rxeq;
/* [0x60] SerDes control */
uint32_t multi_rx_dvalid;
/* [0x64] SerDes control */
uint32_t reserved;
uint32_t rsrvd[6];
};
struct al_serdes_regs {
uint32_t rsrvd_0[64];
struct serdes_gen gen; /* [0x100] */
struct serdes_lane lane[4]; /* [0x200] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* Date of release */
#define SERDES_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define SERDES_GEN_VERSION_DATE_DAY_SHIFT 16
/* Month of release */
#define SERDES_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define SERDES_GEN_VERSION_DATA_MONTH_SHIFT 21
/* Year of release (starting from 2000) */
#define SERDES_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define SERDES_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define SERDES_GEN_VERSION_RESERVED_MASK 0xC0000000
#define SERDES_GEN_VERSION_RESERVED_SHIFT 30
/**** reg_addr register ****/
/* Address value */
#define SERDES_GEN_REG_ADDR_VAL_MASK 0x0000FFFF
#define SERDES_GEN_REG_ADDR_VAL_SHIFT 0
/**** reg_data register ****/
/* Data value */
#define SERDES_GEN_REG_DATA_VAL_MASK 0x000000FF
#define SERDES_GEN_REG_DATA_VAL_SHIFT 0
/**** ICTL_MULTI_BIST register ****/
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_SHIFT 0
/**** ICTL_PCS register ****/
#define SERDES_GEN_ICTL_PCS_EN_NT (1 << 0)
/**** ICTL_PMA register ****/
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT 0
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_REF \
(0 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_L2R \
(4 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_MASK 0x00000070
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT 4
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_MASK 0x00000700
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT 8
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_L2R \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_THIS (0 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_MASTER (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A (1 << 12)
#define SERDES_GEN_ICTL_PMA_SYNTHCKBYPASSEN_NT (1 << 13)
/**** IPD_MULTI_SYNTH register ****/
#define SERDES_GEN_IPD_MULTI_SYNTH_B (1 << 0)
/**** IRST register ****/
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A (1 << 0)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A (1 << 1)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A (1 << 2)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A (1 << 3)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A (1 << 4)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A (1 << 5)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A (1 << 6)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A (1 << 7)
#define SERDES_GEN_IRST_MULTI_HARD_SYNTH_B_A (1 << 8)
#define SERDES_GEN_IRST_POR_B_A (1 << 12)
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A_SEL (1 << 16)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A_SEL (1 << 17)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A_SEL (1 << 18)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL (1 << 19)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A_SEL (1 << 20)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A_SEL (1 << 21)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A_SEL (1 << 22)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A_SEL (1 << 23)
/**** OCTL_MULTI_SYNTHREADY register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHREADY_A (1 << 0)
/**** OCTL_MULTI_SYNTHSTATUS register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHSTATUS_A (1 << 0)
/**** clk_out register ****/
#define SERDES_GEN_CLK_OUT_SEL_MASK 0x0000003F
#define SERDES_GEN_CLK_OUT_SEL_SHIFT 0
/**** OCTL_PMA register ****/
#define SERDES_LANE_OCTL_PMA_TXSTATUS_L_A (1 << 0)
/**** ICTL_MULTI_ANDME register ****/
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A (1 << 0)
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A_SEL (1 << 1)
/**** ICTL_MULTI_LB register ****/
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXIOTIMEDEN_L_NT (1 << 0)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT (1 << 1)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT (1 << 2)
#define SERDES_LANE_ICTL_MULTI_LB_PARRX2TXTIMEDEN_L_NT (1 << 3)
#define SERDES_LANE_ICTL_MULTI_LB_CDRCLK2TXEN_L_NT (1 << 4)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT_SEL (1 << 8)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT_SEL (1 << 9)
/**** ICTL_MULTI_RXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_RXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI_TXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_TXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI register ****/
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_MASK 0x00000003
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SEL (1 << 2)
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_SHIFT 4
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATAEN_L_A (1 << 8)
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATA_L_A (1 << 9)
#define SERDES_LANE_ICTL_MULTI_TXBEACON_L_A (1 << 12)
#define SERDES_LANE_ICTL_MULTI_TXDETECTRXREQ_L_A (1 << 13)
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_MASK 0x00070000
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SHIFT 16
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SEL (1 << 19)
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_MASK 0x00700000
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SHIFT 20
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SEL (1 << 23)
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_MASK 0x07000000
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_SHIFT 24
#define SERDES_LANE_ICTL_MULTI_TXAMP_EN_L (1 << 27)
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_MASK 0x70000000
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_SHIFT 28
/**** ICTL_MULTI_RXEQ register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_EN_L (1 << 0)
#define SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A (1 << 1)
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_SHIFT 4
/**** ICTL_MULTI_RXEQ_L_high register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_L_HIGH_VAL (1 << 0)
/**** ICTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_ICTL_MULTI_RXEYEDIAG_START_L_A (1 << 0)
/**** ICTL_MULTI_TXDEEMPH register ****/
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_MASK 0x0003FFFF
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_MASK 0x7c0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_SHIFT 6
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_MASK 0xf000
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_SHIFT 12
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_MASK 0x7
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_SHIFT 0
/**** ICTL_MULTI_TXMARGIN register ****/
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_MASK 0x00000007
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_SHIFT 0
/**** ICTL_MULTI_TXSWING register ****/
#define SERDES_LANE_ICTL_MULTI_TXSWING_L (1 << 0)
/**** IDAT_MULTI register ****/
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_MASK 0x0000000F
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SHIFT 0
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SEL (1 << 4)
/**** IPD_MULTI register ****/
#define SERDES_LANE_IPD_MULTI_TX_L_B (1 << 0)
#define SERDES_LANE_IPD_MULTI_RX_L_B (1 << 1)
/**** OCTL_MULTI_RXBIST register ****/
#define SERDES_LANE_OCTL_MULTI_RXBIST_DONE_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXBIST_RXLOCKED_L_A (1 << 1)
/**** OCTL_MULTI register ****/
#define SERDES_LANE_OCTL_MULTI_RXCDRLOCK2DATA_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A (1 << 1)
#define SERDES_LANE_OCTL_MULTI_RXREADY_L_A (1 << 2)
#define SERDES_LANE_OCTL_MULTI_RXSTATUS_L_A (1 << 3)
#define SERDES_LANE_OCTL_MULTI_TXREADY_L_A (1 << 4)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXSTAT_L_A (1 << 5)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXACK_L_A (1 << 6)
#define SERDES_LANE_OCTL_MULTI_RXSIGNALDETECT_L_A (1 << 7)
/**** OCTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_MASK 0x00003FFF
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_SHIFT 0
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_DONE_L_A (1 << 16)
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_ERR_L_A (1 << 17)
/**** ODAT_MULTI_RXBIST register ****/
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_MASK 0x0000FFFF
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_SHIFT 0
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_OVERFLOW_L_A (1 << 16)
/**** ODAT_MULTI_RXEQ register ****/
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_MASK 0x00003FFF
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_SHIFT 0
/**** MULTI_RX_DVALID register ****/
#define SERDES_LANE_MULTI_RX_DVALID_MASK_CDR_LOCK (1 << 0)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SIGNALDETECT (1 << 1)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_TX_READY (1 << 2)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_READY (1 << 3)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SYNT_READY (1 << 4)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_ELECIDLE (1 << 5)
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_MASK 0x00FF0000
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_SHIFT 16
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_SEL (1 << 24)
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_VAL (1 << 25)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_SEL (1 << 26)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_VAL (1 << 27)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_SEL (1 << 28)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_VAL (1 << 29)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_SEL (1 << 30)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_VAL (1 << 31)
/**** reserved register ****/
#define SERDES_LANE_RESERVED_OUT_MASK 0x000000FF
#define SERDES_LANE_RESERVED_OUT_SHIFT 0
#define SERDES_LANE_RESERVED_IN_MASK 0x00FF0000
#define SERDES_LANE_RESERVED_IN_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_serdes_REGS_H__ */
/** @} end of ... group */

View File

@ -0,0 +1,875 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_api API
* SerDes HAL driver API
* @ingroup group_serdes SerDes
* @{
*
* @file al_hal_serdes_interface.h
*
* @brief Header file for the SerDes HAL driver
*
*/
#ifndef __AL_HAL_SERDES_INTERFACE_H__
#define __AL_HAL_SERDES_INTERFACE_H__
#include "al_hal_common.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
enum al_serdes_type {
AL_SRDS_TYPE_HSSP,
AL_SRDS_TYPE_25G,
};
enum al_serdes_reg_page {
/* Relevant to Serdes hssp and 25g */
AL_SRDS_REG_PAGE_0_LANE_0 = 0,
AL_SRDS_REG_PAGE_1_LANE_1,
/* Relevant to Serdes hssp only */
AL_SRDS_REG_PAGE_2_LANE_2,
AL_SRDS_REG_PAGE_3_LANE_3,
/* Relevant to Serdes hssp and 25g */
AL_SRDS_REG_PAGE_4_COMMON,
/* Relevant to Serdes hssp only */
AL_SRDS_REG_PAGE_0123_LANES_0123 = 7,
/* Relevant to Serdes 25g only */
AL_SRDS_REG_PAGE_TOP,
};
/* Relevant to Serdes hssp only */
enum al_serdes_reg_type {
AL_SRDS_REG_TYPE_PMA = 0,
AL_SRDS_REG_TYPE_PCS,
};
enum al_serdes_lane {
AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0,
AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1,
AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2,
AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3,
AL_SRDS_NUM_LANES,
AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123,
};
/** Serdes loopback mode */
enum al_serdes_lb_mode {
/** No loopback */
AL_SRDS_LB_MODE_OFF,
/**
* Transmits the untimed, partial equalized RX signal out the transmit
* IO pins.
* No clock used (untimed)
*/
AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX,
/**
* Loops back the TX serializer output into the CDR.
* CDR recovered bit clock used (without attenuation)
*/
AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX,
/**
* Loops back the TX driver IO signal to the RX IO pins
* CDR recovered bit clock used (only through IO)
*/
AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO,
/**
* Parallel loopback from the PMA receive lane data ports, to the
* transmit lane data ports
* CDR recovered bit clock used
*/
AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX,
/** Loops received data after elastic buffer to transmit path */
AL_SRDS_LB_MODE_PCS_PIPE,
/** Loops TX data (to PMA) to RX path (instead of PMA data) */
AL_SRDS_LB_MODE_PCS_NEAR_END,
/** Loops receive data prior to interface block to transmit path */
AL_SRDS_LB_MODE_PCS_FAR_END,
};
enum al_serdes_clk_freq {
AL_SRDS_CLK_FREQ_NA,
AL_SRDS_CLK_FREQ_100_MHZ,
AL_SRDS_CLK_FREQ_125_MHZ,
AL_SRDS_CLK_FREQ_156_MHZ,
};
enum al_serdes_clk_src {
AL_SRDS_CLK_SRC_LOGIC_0,
AL_SRDS_CLK_SRC_REF_PINS,
AL_SRDS_CLK_SRC_R2L,
AL_SRDS_CLK_SRC_R2L_PLL,
AL_SRDS_CLK_SRC_L2R,
};
/** Serdes BIST pattern */
enum al_serdes_bist_pattern {
AL_SRDS_BIST_PATTERN_USER,
AL_SRDS_BIST_PATTERN_PRBS7,
AL_SRDS_BIST_PATTERN_PRBS23,
AL_SRDS_BIST_PATTERN_PRBS31,
AL_SRDS_BIST_PATTERN_CLK1010,
};
/** SerDes group rate */
enum al_serdes_rate {
AL_SRDS_RATE_1_8,
AL_SRDS_RATE_1_4,
AL_SRDS_RATE_1_2,
AL_SRDS_RATE_FULL,
};
/** SerDes power mode */
enum al_serdes_pm {
AL_SRDS_PM_PD,
AL_SRDS_PM_P2,
AL_SRDS_PM_P1,
AL_SRDS_PM_P0S,
AL_SRDS_PM_P0,
};
/**
* Tx de-emphasis parameters
*/
enum al_serdes_tx_deemph_param {
AL_SERDES_TX_DEEMP_C_ZERO, /*< c(0) */
AL_SERDES_TX_DEEMP_C_PLUS, /*< c(1) */
AL_SERDES_TX_DEEMP_C_MINUS, /*< c(-1) */
};
struct al_serdes_adv_tx_params {
/*
* select the input values location.
* When set to true the values will be taken from the internal registers
* that will be override with the next following parameters.
* When set to false the values will be taken from external pins (the
* other parameters in this case is not needed)
*/
al_bool override;
/*
* Transmit Amplitude control signal. Used to define the full-scale
* maximum swing of the driver.
* 000 - Not Supported
* 001 - 952mVdiff-pkpk
* 010 - 1024mVdiff-pkpk
* 011 - 1094mVdiff-pkpk
* 100 - 1163mVdiff-pkpk
* 101 - 1227mVdiff-pkpk
* 110 - 1283mVdiff-pkpk
* 111 - 1331mVdiff-pkpk
*/
uint8_t amp;
/* Defines the total number of driver units allocated in the driver */
uint8_t total_driver_units;
/* Defines the total number of driver units allocated to the
* first post-cursor (C+1) tap. */
uint8_t c_plus_1;
/* Defines the total number of driver units allocated to the
* second post-cursor (C+2) tap. */
uint8_t c_plus_2;
/* Defines the total number of driver units allocated to the
* first pre-cursor (C-1) tap. */
uint8_t c_minus_1;
/* TX driver Slew Rate control:
* 00 - 31ps
* 01 - 33ps
* 10 - 68ps
* 11 - 170ps
*/
uint8_t slew_rate;
};
struct al_serdes_adv_rx_params {
/*
* select the input values location.
* When set to true the values will be taken from the internal registers
* that will be override with the next following parameters.
* When set to false the values will be taken based in the equalization
* results (the other parameters in this case is not needed)
*/
al_bool override;
/* RX agc high frequency dc gain:
* -3'b000: -3dB
* -3'b001: -2.5dB
* -3'b010: -2dB
* -3'b011: -1.5dB
* -3'b100: -1dB
* -3'b101: -0.5dB
* -3'b110: -0dB
* -3'b111: 0.5dB
*/
uint8_t dcgain;
/* DFE post-shaping tap 3dB frequency
* -3'b000: 684MHz
* -3'b001: 576MHz
* -3'b010: 514MHz
* -3'b011: 435MHz
* -3'b100: 354MHz
* -3'b101: 281MHz
* -3'b110: 199MHz
* -3'b111: 125MHz
*/
uint8_t dfe_3db_freq;
/* DFE post-shaping tap gain
* 0: no pulse shaping tap
* 1: -24mVpeak
* 2: -45mVpeak
* 3: -64mVpeak
* 4: -80mVpeak
* 5: -93mVpeak
* 6: -101mVpeak
* 7: -105mVpeak
*/
uint8_t dfe_gain;
/* DFE first tap gain control
* -4'b0000: +1mVpeak
* -4'b0001: +10mVpeak
* ....
* -4'b0110: +55mVpeak
* -4'b0111: +64mVpeak
* -4'b1000: -1mVpeak
* -4'b1001: -10mVpeak
* ....
* -4'b1110: -55mVpeak
* -4'b1111: -64mVpeak
*/
uint8_t dfe_first_tap_ctrl;
/* DFE second tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +9mVpeak
* ....
* -4'b0110: +46mVpeak
* -4'b0111: +53mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -9mVpeak
* ....
* -4'b1110: -46mVpeak
* -4'b1111: -53mVpeak
*/
uint8_t dfe_secound_tap_ctrl;
/* DFE third tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +7mVpeak
* ....
* -4'b0110: +38mVpeak
* -4'b0111: +44mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -7mVpeak
* ....
* -4'b1110: -38mVpeak
* -4'b1111: -44mVpeak
*/
uint8_t dfe_third_tap_ctrl;
/* DFE fourth tap gain control
* -4'b0000: +0mVpeak
* -4'b0001: +6mVpeak
* ....
* -4'b0110: +29mVpeak
* -4'b0111: +33mVpeak
* -4'b1000: -0mVpeak
* -4'b1001: -6mVpeak
* ....
* -4'b1110: -29mVpeak
* -4'b1111: -33mVpeak
*/
uint8_t dfe_fourth_tap_ctrl;
/* Low frequency agc gain (att) select
* -3'b000: Disconnected
* -3'b001: -18.5dB
* -3'b010: -12.5dB
* -3'b011: -9dB
* -3'b100: -6.5dB
* -3'b101: -4.5dB
* -3'b110: -2.9dB
* -3'b111: -1.6dB
*/
uint8_t low_freq_agc_gain;
/* Provides a RX Equalizer pre-hint, prior to beginning
* adaptive equalization */
uint8_t precal_code_sel;
/* High frequency agc boost control
* Min d0: Boost ~4dB
* Max d31: Boost ~20dB
*/
uint8_t high_freq_agc_boost;
};
struct al_serdes_25g_adv_rx_params {
/* ATT (PLE Flat-Band Gain) */
uint8_t att;
/* APG (CTLE's Flat-Band Gain) */
uint8_t apg;
/* LFG (Low-Freq Gain) */
uint8_t lfg;
/* HFG (High-Freq Gain) */
uint8_t hfg;
/* MBG (MidBand-Freq-knob Gain) */
uint8_t mbg;
/* MBF (MidBand-Freq-knob Frequency position Gain) */
uint8_t mbf;
/* DFE Tap1 even#0 Value */
int8_t dfe_first_tap_even0_ctrl;
/* DFE Tap1 even#1 Value */
int8_t dfe_first_tap_even1_ctrl;
/* DFE Tap1 odd#0 Value */
int8_t dfe_first_tap_odd0_ctrl;
/* DFE Tap1 odd#1 Value */
int8_t dfe_first_tap_odd1_ctrl;
/* DFE Tap2 Value */
int8_t dfe_second_tap_ctrl;
/* DFE Tap3 Value */
int8_t dfe_third_tap_ctrl;
/* DFE Tap4 Value */
int8_t dfe_fourth_tap_ctrl;
/* DFE Tap5 Value */
int8_t dfe_fifth_tap_ctrl;
};
struct al_serdes_25g_tx_diag_info {
uint8_t regulated_supply;
int8_t dcd_trim;
uint8_t clk_delay;
uint8_t calp_multiplied_by_2;
uint8_t caln_multiplied_by_2;
};
struct al_serdes_25g_rx_diag_info {
int8_t los_offset;
int8_t agc_offset;
int8_t leq_gainstage_offset;
int8_t leq_eq1_offset;
int8_t leq_eq2_offset;
int8_t leq_eq3_offset;
int8_t leq_eq4_offset;
int8_t leq_eq5_offset;
int8_t summer_even_offset;
int8_t summer_odd_offset;
int8_t vscan_even_offset;
int8_t vscan_odd_offset;
int8_t data_slicer_even0_offset;
int8_t data_slicer_even1_offset;
int8_t data_slicer_odd0_offset;
int8_t data_slicer_odd1_offset;
int8_t edge_slicer_even_offset;
int8_t edge_slicer_odd_offset;
int8_t eye_slicer_even_offset;
int8_t eye_slicer_odd_offset;
uint8_t cdr_clk_i;
uint8_t cdr_clk_q;
uint8_t cdr_dll;
uint8_t cdr_vco_dosc;
uint8_t cdr_vco_fr;
uint16_t cdr_dlpf;
uint8_t ple_resistance;
uint8_t rx_term_mode;
uint8_t rx_coupling;
uint8_t rx_term_cal_code;
uint8_t rx_sheet_res_cal_code;
};
/**
* SRIS parameters
*/
struct al_serdes_sris_params {
/* Controls the frequency accuracy threshold (ppm) for lock detection CDR */
uint16_t ppm_drift_count;
/* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */
uint16_t ppm_drift_max;
/* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */
uint16_t synth_ppm_drift_max;
/* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */
uint8_t full_d2r1;
/* Elastic buffer full threshold for PCIE modes: GEN3 */
uint8_t full_pcie_g3;
/* Elastic buffer midpoint threshold.
* Sets the depth of the buffer while in PCIE mode, GEN1/GEN2
*/
uint8_t rd_threshold_d2r1;
/* Elastic buffer midpoint threshold.
* Sets the depth of the buffer while in PCIE mode, GEN3
*/
uint8_t rd_threshold_pcie_g3;
};
/** SerDes PCIe Rate - values are important for proper behavior */
enum al_serdes_pcie_rate {
AL_SRDS_PCIE_RATE_GEN1 = 0,
AL_SRDS_PCIE_RATE_GEN2,
AL_SRDS_PCIE_RATE_GEN3,
};
struct al_serdes_grp_obj {
void __iomem *regs_base;
/**
* get the type of the serdes.
* Must be implemented for all SerDes unit.
*
* @return the serdes type.
*/
enum al_serdes_type (*type_get)(void);
/**
* Reads a SERDES internal register
*
* @param obj The object context
* @param page The SERDES register page within the group
* @param type The SERDES register type (PMA /PCS)
* @param offset The SERDES register offset (0 - 4095)
* @param data The read data
*
* @return 0 if no error found.
*/
int (*reg_read)(struct al_serdes_grp_obj *, enum al_serdes_reg_page,
enum al_serdes_reg_type, uint16_t, uint8_t *);
/**
* Writes a SERDES internal register
*
* @param obj The object context
* @param page The SERDES register page within the group
* @param type The SERDES register type (PMA /PCS)
* @param offset The SERDES register offset (0 - 4095)
* @param data The data to write
*
* @return 0 if no error found.
*/
int (*reg_write)(struct al_serdes_grp_obj *, enum al_serdes_reg_page,
enum al_serdes_reg_type, uint16_t, uint8_t);
/**
* Enable BIST required overrides
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The required speed rate
*/
void (*bist_overrides_enable)(struct al_serdes_grp_obj *, enum al_serdes_rate);
/**
* Disable BIST required overrides
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The required speed rate
*/
void (*bist_overrides_disable)(struct al_serdes_grp_obj *);
/**
* Rx rate change
*
* @param obj The object context
* @param grp The SERDES group
* @param rate The Rx required rate
*/
void (*rx_rate_change)(struct al_serdes_grp_obj *, enum al_serdes_rate);
/**
* SERDES lane Rx rate change software flow enable
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
void (*rx_rate_change_sw_flow_en)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* SERDES lane Rx rate change software flow disable
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
void (*rx_rate_change_sw_flow_dis)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate override check
*
* @param obj The object context
* @param grp The SERDES group
* @param lane The SERDES lane within the group
*
* @returns AL_TRUE if the override is enabled
*/
al_bool (*pcie_rate_override_is_enabled)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate override control
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param en Enable/disable
*/
void (*pcie_rate_override_enable_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
al_bool en);
/**
* PCIe lane rate get
*
* @param obj The object context
* @param lane The SERDES lane within the group
*/
enum al_serdes_pcie_rate (*pcie_rate_get)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* PCIe lane rate set
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param rate The required rate
*/
void (*pcie_rate_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_pcie_rate rate);
/**
* SERDES group power mode control
*
* @param obj The object context
* @param grp The SERDES group
* @param pm The required power mode
*/
void (*group_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_pm);
/**
* SERDES lane power mode control
*
* @param obj The object context
* @param grp The SERDES group
* @param lane The SERDES lane within the group
* @param rx_pm The required RX power mode
* @param tx_pm The required TX power mode
*/
void (*lane_pm_set)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_pm, enum al_serdes_pm);
/**
* SERDES group PMA hard reset
* Controls Serdes group PMA hard reset
*
* @param obj The object context
* @param grp The SERDES group
* @param enable Enable/disable hard reset
*/
void (*pma_hard_reset_group)(struct al_serdes_grp_obj *, al_bool);
/**
* SERDES lane PMA hard reset
* Controls Serdes lane PMA hard reset
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable/disable hard reset
*/
void (*pma_hard_reset_lane)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* Configure SERDES loopback
* Controls the loopback
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param mode The requested loopback mode
*/
void (*loopback_control)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_lb_mode);
/**
* SERDES BIST pattern selection
* Selects the BIST pattern to be used
*
* @param obj The object context
* @param pattern The pattern to set
* @param user_data The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER)
* 80 bits (8 bytes array)
*/
void (*bist_pattern_select)(struct al_serdes_grp_obj *,
enum al_serdes_bist_pattern, uint8_t *);
/**
* SERDES BIST TX Enable
* Enables/disables TX BIST per lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable or disable TX BIST
*/
void (*bist_tx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* SERDES BIST TX single bit error injection
* Injects single bit error during a TX BIST
*
* @param obj The object context
*/
void (*bist_tx_err_inject)(struct al_serdes_grp_obj *);
/**
* SERDES BIST RX Enable
* Enables/disables RX BIST per lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param enable Enable or disable TX BIST
*/
void (*bist_rx_enable)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool);
/**
* SERDES BIST RX status
* Checks the RX BIST status for a specific SERDES lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param is_locked An indication whether RX BIST is locked
* @param err_cnt_overflow An indication whether error count overflow occured
* @param err_cnt Current bit error count
*/
void (*bist_rx_status)(struct al_serdes_grp_obj *, enum al_serdes_lane, al_bool *,
al_bool *, uint32_t *);
/**
* Set the tx de-emphasis to preset values
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
*/
void (*tx_deemph_preset)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Increase tx de-emphasis param.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param param which tx de-emphasis to change
*
* @return false in case max is reached. true otherwise.
*/
al_bool (*tx_deemph_inc)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_tx_deemph_param);
/**
* Decrease tx de-emphasis param.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param param which tx de-emphasis to change
*
* @return false in case min is reached. true otherwise.
*/
al_bool (*tx_deemph_dec)(struct al_serdes_grp_obj *, enum al_serdes_lane,
enum al_serdes_tx_deemph_param);
/**
* run Rx eye measurement.
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param timeout timeout in uSec
* @param value Rx eye measurement value
* (0 - completely closed eye, 0xffff - completely open eye).
*
* @return 0 if no error found.
*/
int (*eye_measure_run)(struct al_serdes_grp_obj *, enum al_serdes_lane,
uint32_t, unsigned int *);
/**
* Eye diagram single sampling
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI)
* @param y Sampling Y position (0 - 62 --> 500mV ... -500mV)
* @param timeout timeout in uSec
* @param value Eye diagram sample value (BER - 0x0000 - 0xffff)
*
* @return 0 if no error found.
*/
int (*eye_diag_sample)(struct al_serdes_grp_obj *, enum al_serdes_lane,
unsigned int, int, unsigned int, unsigned int *);
/**
* Eye diagram full run
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param x_start Sampling from X position
* @param x_stop Sampling to X position
* @param x_step jump in x_step
* @param y_start Sampling from Y position
* @param y_stop Sampling to Y position
* @param y_step jump in y_step
* @param num_bits_per_sample How many bits to check
* @param buf array of results
* @param buf_size array size - must be equal to
* (((y_stop - y_start) / y_step) + 1) *
* (((x_stop - x_start) / x_step) + 1)
*
* @return 0 if no error found.
*/
int (*eye_diag_run)(struct al_serdes_grp_obj *, enum al_serdes_lane,
int, int, unsigned int, int, int, unsigned int, uint64_t, uint64_t *,
uint32_t);
/**
* Check if signal is detected
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if signal is detected. false otherwise.
*/
al_bool (*signal_is_detected)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Check if CDR is locked
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if cdr is locked. false otherwise.
*/
al_bool (*cdr_is_locked)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* Check if rx is valid for this lane
*
* @param obj The object context
* @param lane The SERDES lane within the group
*
* @return true if rx is valid. false otherwise.
*/
al_bool (*rx_valid)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* configure tx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx parameters
*/
void (*tx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* read tx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx parameters
*/
void (*tx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* configure rx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx parameters
*/
void (*rx_advanced_params_set)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* read rx advanced parameters
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx parameters
*/
void (*rx_advanced_params_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void *);
/**
* Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock
*
* @param obj The object context
*
*/
void (*mode_set_sgmii)(struct al_serdes_grp_obj *);
/**
* Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock
*
* @param obj The object context
*
*/
void (*mode_set_kr)(struct al_serdes_grp_obj *);
/**
* performs SerDes HW equalization test and update equalization parameters
*
* @param obj the object context
* @param lane The SERDES lane within the group
*/
int (*rx_equalization)(struct al_serdes_grp_obj *, enum al_serdes_lane);
/**
* performs Rx equalization and compute the width and height of the eye
*
* @param obj the object context
* @param lane The SERDES lane within the group
* @param width the output width of the eye
* @param height the output height of the eye
*/
int (*calc_eye_size)(struct al_serdes_grp_obj *, enum al_serdes_lane, int *, int *);
/**
* SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking)
* Currently available only for PCIe interfaces.
* When working with local Refclk, same SRIS configuration in both serdes sides
* (EP and RC in PCIe interface) is required.
*
* performs SRIS configuration according to params
*
* @param obj the object context
* @param params the SRIS parameters
*/
void (*sris_config)(struct al_serdes_grp_obj *, void *);
/**
* set SERDES dcgain parameter
*
* @param obj the object context
* @param dcgain dcgain value to set
*/
void (*dcgain_set)(struct al_serdes_grp_obj *, uint8_t);
/**
* read tx diagnostics info
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the tx diagnostics info structure
*/
void (*tx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*);
/**
* read rx diagnostics info
*
* @param obj The object context
* @param lane The SERDES lane within the group
* @param params pointer to the rx diagnostics info structure
*/
void (*rx_diag_info_get)(struct al_serdes_grp_obj *, enum al_serdes_lane, void*);
};
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_HAL_SERDES_INTERFACE_H__ */
/** @} end of SERDES group */

View File

@ -0,0 +1,750 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_SERDES_INTERNAL_REGS_H__
#define __AL_SERDES_INTERNAL_REGS_H__
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Per lane register fields
******************************************************************************/
/*
* RX and TX lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT 0x01
/*
* RX and TX lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS 0x02
/* RX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM 3
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0 0x10
/* TX lane power state control */
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM 4
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK 0x1f
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD 0x01
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2 0x02
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1 0x04
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S 0x08
#define SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0 0x10
/* RX lane word width */
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_10 0x01
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_16 0x02
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 0x03
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_32 0x04
#define SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_40 0x05
/* TX lane word width */
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM 5
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_8 0x00
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_10 0x10
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_16 0x20
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20 0x30
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_32 0x40
#define SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_40 0x50
/* RX lane rate select */
#define SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSRX_DIVRATE_MASK 0x07
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4 0x01
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2 0x02
#define SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1 0x03
/* TX lane rate select */
#define SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM 6
#define SERDES_IREG_FLD_PCSTX_DIVRATE_MASK 0x70
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8 0x00
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4 0x10
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2 0x20
#define SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1 0x30
/*
* PMA serial RX-to-TX loop-back enable (from AGC to IO Driver). Serial receive
* to transmit loopback: 0 - Disables loopback 1 - Transmits the untimed,
* partial equalized RX signal out the transmit IO pins
*/
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN 0x10
/*
* PMA TX-to-RX buffered serial loop-back enable (bypasses IO Driver). Serial
* transmit to receive buffered loopback: 0 - Disables loopback 1 - Loops back
* the TX serializer output into the CDR
*/
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN 0x20
/*
* PMA TX-to-RX I/O serial loop-back enable (loop back done directly from TX to
* RX pads). Serial IO loopback from the transmit lane IO pins to the receive
* lane IO pins: 0 - Disables loopback 1 - Loops back the driver IO signal to
* the RX IO pins
*/
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN 0x40
/*
* PMA Parallel RX-to-TX loop-back enable. Parallel loopback from the PMA
* receive lane 20-bit data ports, to the transmit lane 20-bit data ports 0 -
* Disables loopback 1 - Loops back the 20-bit receive data port to the
* transmitter
*/
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN 0x80
/*
* PMA CDR recovered-clock loopback enable; asserted when PARRX2TXTIMEDEN is 1.
* Transmit bit clock select: 0 - Selects synthesizer bit clock for transmit 1
* - Selects CDR clock for transmit
*/
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM 7
#define SERDES_IREG_FLD_LB_CDRCLK2TXEN 0x01
/* Receive lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSRXBIST_EN 0x01
/* TX lane BIST enable. Active High */
#define SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM 8
#define SERDES_IREG_FLD_PCSTXBIST_EN 0x02
/*
* RX BIST completion signal 0 - Indicates test is not completed 1 - Indicates
* the test has completed, and will remain high until a new test is initiated
*/
#define SERDES_IREG_FLD_RXBIST_DONE_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_DONE 0x04
/*
* RX BIST error count overflow indicator. Indicates an overflow in the number
* of byte errors identified during the course of the test. This word is stable
* to sample when *_DONE_* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW 0x08
/*
* RX BIST locked indicator 0 - Indicates BIST is not word locked and error
* comparisons have not begun yet 1 - Indicates BIST is word locked and error
* comparisons have begun
*/
#define SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM 8
#define SERDES_IREG_FLD_RXBIST_RXLOCKED 0x10
/*
* RX BIST error count word. Indicates the number of byte errors identified
* during the course of the test. This word is stable to sample when *_DONE_*
* signal has asserted
*/
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM 9
#define SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM 10
/* Tx params */
#define SERDES_IREG_TX_DRV_1_REG_NUM 21
#define SERDES_IREG_TX_DRV_1_HLEV_MASK 0x7
#define SERDES_IREG_TX_DRV_1_HLEV_SHIFT 0
#define SERDES_IREG_TX_DRV_1_LEVN_MASK 0xf8
#define SERDES_IREG_TX_DRV_1_LEVN_SHIFT 3
#define SERDES_IREG_TX_DRV_2_REG_NUM 22
#define SERDES_IREG_TX_DRV_2_LEVNM1_MASK 0xf
#define SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT 0
#define SERDES_IREG_TX_DRV_2_LEVNM2_MASK 0x30
#define SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT 4
#define SERDES_IREG_TX_DRV_3_REG_NUM 23
#define SERDES_IREG_TX_DRV_3_LEVNP1_MASK 0x7
#define SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT 0
#define SERDES_IREG_TX_DRV_3_SLEW_MASK 0x18
#define SERDES_IREG_TX_DRV_3_SLEW_SHIFT 3
/* Rx params */
#define SERDES_IREG_RX_CALEQ_1_REG_NUM 24
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT 0
/* DFE post-shaping tap 3dB frequency */
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK 0x38
#define SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT 3
#define SERDES_IREG_RX_CALEQ_2_REG_NUM 25
/* DFE post-shaping tap gain */
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK 0x7
#define SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT 0
/* DFE first tap gain control */
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK 0x78
#define SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT 3
#define SERDES_IREG_RX_CALEQ_3_REG_NUM 26
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK 0xf0
#define SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_4_REG_NUM 27
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK 0xf
#define SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT 0
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK 0x70
#define SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT 4
#define SERDES_IREG_RX_CALEQ_5_REG_NUM 28
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK 0x7
#define SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT 0
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK 0xf8
#define SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT 3
/* RX lane best eye point measurement result */
#define SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM 29
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM 30
#define SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK 0x3F
/*
* Adaptive RX Equalization enable
* 0 - Disables adaptive RX equalization.
* 1 - Enables adaptive RX equalization.
*/
#define SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM 31
#define SERDES_IREG_FLD_PCSRXEQ_START (1 << 0)
/*
* Enables an eye diagram measurement
* within the PHY.
* 0 - Disables eye diagram measurement
* 1 - Enables eye diagram measurement
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM 31
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START (1 << 1)
/*
* RX lane single roam eye point measurement start signal.
* If asserted, single measurement at fix XADJUST and YADJUST is started.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM 31
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START (1 << 2)
/*
* PHY Eye diagram measurement status
* signal
* 0 - Indicates eye diagram results are not
* valid for sampling
* 1 - Indicates eye diagram is complete and
* results are valid for sampling
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE (1 << 0)
/*
* Eye diagram error signal. Indicates if the
* measurement was invalid because the eye
* diagram was interrupted by the link entering
* electrical idle.
* 0 - Indicates eye diagram is valid
* 1- Indicates an error occurred, and the eye
* diagram measurement should be re-run
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR_REG_NUM 32
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR (1 << 1)
/*
* PHY Adaptive Equalization status
* 0 - Indicates Adaptive Equalization results are not valid for sampling
* 1 - Indicates Adaptive Equalization is complete and results are valid for
* sampling
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM 32
#define SERDES_IREG_FLD_RXCALROAMEYEMEASDONE (1 << 2)
/*
*
* PHY Adaptive Equalization Status Signal
* 0 Indicates adaptive equalization results
* are not valid for sampling
* 1 Indicates adaptive equalization is
* complete and results are valid for sampling.
*/
#define SERDES_IREG_FLD_RXEQ_DONE_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_DONE (1 << 3)
/*
* 7-bit eye diagram time adjust control
* - 6-bits per UI
* - spans 2 UI
*/
#define SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM 33
/* 6-bit eye diagram voltage adjust control - spans +/-300mVdiff */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM 34
/*
* Eye diagram status signal. Safe for
* sampling when *DONE* signal has
* asserted
* 14'h0000 - Completely Closed Eye
* 14'hFFFF - Completely Open Eye
*/
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM 35
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_MAKE 0xFF
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM 36
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE 0x3F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_SHIFT 0
/*
* RX lane single roam eye point measurement result.
* If 0, eye is open at current XADJUST and YADJUST settings.
*/
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM 37
#define SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM 38
/*
* Override enable for CDR lock to reference clock
* 0 - CDR is always locked to reference
* 1 - CDR operation mode (Lock2Reference or Lock2data are controlled internally
* depending on the incoming signal and ppm status)
*/
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM 39
#define SERDES_IREG_FLD_RXLOCK2REF_OVREN (1 << 1)
/*
* Selects Eye to capture based on edge
* 0 - Capture 1st Eye in Eye Diagram
* 1 - Capture 2nd Eye in Eye Diagram measurement
*/
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM 39
#define SERDES_IREG_FLD_RXROAM_XORBITSEL (1 << 2)
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_1ST 0
#define SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND (1 << 2)
/*
* RX Signal detect. 0 indicates no signal, 1 indicates signal detected.
*/
#define SERDES_IREG_FLD_RXRANDET_REG_NUM 41
#define SERDES_IREG_FLD_RXRANDET_STAT 0x20
/*
* RX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_RX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_RX_INV (1 << 0)
/*
* TX data polarity inversion control:
* 1'b0: no inversion
* 1'b1: invert polarity
*/
#define SERDES_IREG_FLD_POLARITY_TX_REG_NUM 46
#define SERDES_IREG_FLD_POLARITY_TX_INV (1 << 1)
/* LANEPCSPSTATE* override enable (Active low) */
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN (1 << 0)
/* LB* override enable (Active low) */
#define SERDES_IREG_FLD_LB_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_LB_LOCWREN (1 << 1)
/* PCSRX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRX_LOCWREN (1 << 4)
/* PCSRXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXBIST_LOCWREN (1 << 5)
/* PCSRXEQ* override enable (Active low) */
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSRXEQ_LOCWREN (1 << 6)
/* PCSTX* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM 85
#define SERDES_IREG_FLD_PCSTX_LOCWREN (1 << 7)
/*
* group registers:
* SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN,
* SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN
* SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN
*/
#define SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM 86
/* PCSTXBIST* override enable (Active low) */
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_PCSTXBIST_LOCWREN (1 << 0)
/* Override RX_CALCEQ through the internal registers (Active low) */
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM 86
#define SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN (1 << 3)
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN (1 << 4)
/* RXCALROAMEYEMEASIN* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN (1 << 6)
/* RXCALROAMXADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM 86
#define SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN (1 << 7)
/* RXCALROAMYADJUST* override enable - Active Low */
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN (1 << 0)
/* RXCDRCALFOSC* override enable. Active Low */
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXCDRCALFOSC_LOCWREN (1 << 1)
/* Over-write enable for RXEYEDIAGFSM_INITXVAL */
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXEYEDIAGFSM_LOCWREN (1 << 2)
/* Over-write enable for CMNCLKGENMUXSEL_TXINTERNAL */
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_RXTERMHIZ_LOCWREN (1 << 3)
/* TXCALTCLKDUTY* override enable. Active Low */
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN_REG_NUM 87
#define SERDES_IREG_FLD_TXCALTCLKDUTY_LOCWREN (1 << 4)
/* Override TX_DRV through the internal registers (Active low) */
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM 87
#define SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN (1 << 5)
/*******************************************************************************
* Common lane register fields - PMA
******************************************************************************/
/*
* Common lane hard reset control
* 0 - Hard reset is taken from the interface pins
* 1 - Hard reset is taken from registers
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK 0x01
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_IFACE 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS 0x01
/*
* Common lane hard reset
* 0 - Hard reset is asserted
* 1 - Hard reset is de-asserted
*/
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM 2
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK 0x02
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT 0x00
#define SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT 0x02
/* Synth power state control */
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM 3
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK 0x1f
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD 0x01
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2 0x02
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1 0x04
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S 0x08
#define SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0 0x10
/* Transmit datapath FIFO enable (Active High) */
#define SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM 8
#define SERDES_IREG_FLD_CMNPCS_TXENABLE (1 << 2)
/*
* RX lost of signal detector enable
* - 0 - disable
* - 1 - enable
*/
#define SERDES_IREG_FLD_RXLOSDET_ENABLE_REG_NUM 13
#define SERDES_IREG_FLD_RXLOSDET_ENABLE AL_BIT(4)
/* Signal Detect Threshold Level */
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXELECIDLE_SIGDETTHRESH_MASK AL_FIELD_MASK(2, 0)
/* LOS Detect Threshold Level */
#define SERDES_IREG_FLD_RXLOSDET_THRESH_REG_NUM 15
#define SERDES_IREG_FLD_RXLOSDET_THRESH_MASK AL_FIELD_MASK(4, 3)
#define SERDES_IREG_FLD_RXLOSDET_THRESH_SHIFT 3
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM 30
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM 31
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM 32
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM 33
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM 34
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK 0x1
#define SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM 35
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT 1
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM 36
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM 37
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT 0
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_REG_NUM 43
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_MASK 0x7
#define SERDES_IREG_FLD_RXEQ_DCGAIN_LUP0_SHIFT 0
#define SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(byte_num) (56 + (byte_num))
#define SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES 10
/*
* Selects the transmit BIST mode:
* 0 - Uses the 80-bit internal memory pattern (w/ OOB)
* 1 - Uses a 27 PRBS pattern
* 2 - Uses a 223 PRBS pattern
* 3 - Uses a 231 PRBS pattern
* 4 - Uses a 1010 clock pattern
* 5 and above - Reserved
*/
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM 80
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK 0x07
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER 0x00
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7 0x01
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23 0x02
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31 0x03
#define SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010 0x04
/* Single-Bit error injection enable (on posedge) */
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM 80
#define SERDES_IREG_FLD_TXBIST_BITERROR_EN 0x20
/* CMNPCIEGEN3* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN (1 << 2)
/* CMNPCS* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCS_LOCWREN (1 << 3)
/* CMNPCSBIST* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSBIST_LOCWREN (1 << 4)
/* CMNPCSPSTATE* override enable (Active Low) */
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM 95
#define SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN (1 << 5)
/* PCS_EN* override enable (Active Low) */
#define SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM 96
#define SERDES_IREG_FLD_PCS_LOCWREN (1 << 3)
/* Eye diagram sample count */
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM 150
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT 0
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM 151
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK 0xff
#define SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT 0
/* override control */
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM 230
#define SERDES_IREG_FLD_RXLOCK2REF_LOCWREN 1 << 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM 623
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM 624
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK 0xff
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT 0
/* X and Y coefficient return value */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM 626
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALWEIGHT_SHIFT 0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_MASK 0xF0
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALWEIGHT_SHIFT 4
/* X coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM 627
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT 0
/* X fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM 628
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK 0x7F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT 0
/* Y coarse scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM 629
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT 0
/* Y fine scan step */
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM 630
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK 0x0F
#define SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT 0
#define SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM 157
#define SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM 158
#define SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM 159
#define SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM 160
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM 163
#define SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM 164
/*******************************************************************************
* Common lane register fields - PCS
******************************************************************************/
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM 3
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK AL_FIELD_MASK(5, 4)
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT 4
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM 6
#define SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA AL_BIT(2)
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM 18
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM 19
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM 20
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK 0x1F
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT 0
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM 21
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK 0x7C
#define SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT 2
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_MASK 0x7f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_ITER_NUM_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_REG_NUM 23
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_REG_NUM 22
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_REG_NUM 24
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_MASK 0x3e
#define SERDES_IREG_FLD_PCS_RXEQ_COARSE_STEP_SHIFT 1
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_REG_NUM 35
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN1_MASK_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_REG_NUM 34
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_MASK 0x80
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_RUN2_MASK_SHIFT 7
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_MASK 0x1f
#define SERDES_IREG_FLD_PCS_RXEQ_FINE_STEP_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_REG_NUM 37
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_MASK 0xff
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_CODE_EN_SHIFT 0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_REG_NUM 36
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_MASK 0xe0
#define SERDES_IREG_FLD_PCS_RXEQ_LOOKUP_LASTCODE_SHIFT 5
#ifdef __cplusplus
}
#endif
#endif /* __AL_serdes_REG_H */

View File

@ -0,0 +1,495 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_serdes_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_SERDES_REGS_H__
#define __AL_HAL_SERDES_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct serdes_gen {
/* [0x0] SerDes Registers Version */
uint32_t version;
uint32_t rsrvd_0[3];
/* [0x10] SerDes register file address */
uint32_t reg_addr;
/* [0x14] SerDes register file data */
uint32_t reg_data;
uint32_t rsrvd_1[2];
/* [0x20] SerDes control */
uint32_t ictl_multi_bist;
/* [0x24] SerDes control */
uint32_t ictl_pcs;
/* [0x28] SerDes control */
uint32_t ictl_pma;
uint32_t rsrvd_2;
/* [0x30] SerDes control */
uint32_t ipd_multi_synth;
/* [0x34] SerDes control */
uint32_t irst;
/* [0x38] SerDes control */
uint32_t octl_multi_synthready;
/* [0x3c] SerDes control */
uint32_t octl_multi_synthstatus;
/* [0x40] SerDes control */
uint32_t clk_out;
uint32_t rsrvd[47];
};
struct serdes_lane {
uint32_t rsrvd1[4];
/* [0x10] SerDes status */
uint32_t octl_pma;
/* [0x14] SerDes control */
uint32_t ictl_multi_andme;
/* [0x18] SerDes control */
uint32_t ictl_multi_lb;
/* [0x1c] SerDes control */
uint32_t ictl_multi_rxbist;
/* [0x20] SerDes control */
uint32_t ictl_multi_txbist;
/* [0x24] SerDes control */
uint32_t ictl_multi;
/* [0x28] SerDes control */
uint32_t ictl_multi_rxeq;
/* [0x2c] SerDes control */
uint32_t ictl_multi_rxeq_l_low;
/* [0x30] SerDes control */
uint32_t ictl_multi_rxeq_l_high;
/* [0x34] SerDes control */
uint32_t ictl_multi_rxeyediag;
/* [0x38] SerDes control */
uint32_t ictl_multi_txdeemph;
/* [0x3c] SerDes control */
uint32_t ictl_multi_txmargin;
/* [0x40] SerDes control */
uint32_t ictl_multi_txswing;
/* [0x44] SerDes control */
uint32_t idat_multi;
/* [0x48] SerDes control */
uint32_t ipd_multi;
/* [0x4c] SerDes control */
uint32_t octl_multi_rxbist;
/* [0x50] SerDes control */
uint32_t octl_multi;
/* [0x54] SerDes control */
uint32_t octl_multi_rxeyediag;
/* [0x58] SerDes control */
uint32_t odat_multi_rxbist;
/* [0x5c] SerDes control */
uint32_t odat_multi_rxeq;
/* [0x60] SerDes control */
uint32_t multi_rx_dvalid;
/* [0x64] SerDes control */
uint32_t reserved;
uint32_t rsrvd[6];
};
struct al_serdes_regs {
uint32_t rsrvd_0[64];
struct serdes_gen gen; /* [0x100] */
struct serdes_lane lane[4]; /* [0x200] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define SERDES_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define SERDES_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* Date of release */
#define SERDES_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define SERDES_GEN_VERSION_DATE_DAY_SHIFT 16
/* Month of release */
#define SERDES_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define SERDES_GEN_VERSION_DATA_MONTH_SHIFT 21
/* Year of release (starting from 2000) */
#define SERDES_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define SERDES_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define SERDES_GEN_VERSION_RESERVED_MASK 0xC0000000
#define SERDES_GEN_VERSION_RESERVED_SHIFT 30
/**** reg_addr register ****/
/* Address value */
#define SERDES_GEN_REG_ADDR_VAL_MASK 0x0000FFFF
#define SERDES_GEN_REG_ADDR_VAL_SHIFT 0
/**** reg_data register ****/
/* Data value */
#define SERDES_GEN_REG_DATA_VAL_MASK 0x000000FF
#define SERDES_GEN_REG_DATA_VAL_SHIFT 0
/**** ICTL_MULTI_BIST register ****/
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_MULTI_BIST_MODESEL_NT_SHIFT 0
/**** ICTL_PCS register ****/
#define SERDES_GEN_ICTL_PCS_EN_NT (1 << 0)
/**** ICTL_PMA register ****/
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_MASK 0x00000007
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT 0
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_REF \
(0 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REF_SEL_NT_L2R \
(4 << (SERDES_GEN_ICTL_PMA_REF_SEL_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_MASK 0x00000070
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT 4
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_R2L \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSRIGHT2LEFT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_MASK 0x00000700
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT 8
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_0 \
(0 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_REF \
(2 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_L2R \
(3 << (SERDES_GEN_ICTL_PMA_REFBUSLEFT2RIGHT_MODE_NT_SHIFT))
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_THIS (0 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A_SRC_MASTER (1 << 11)
#define SERDES_GEN_ICTL_PMA_TXENABLE_A (1 << 12)
#define SERDES_GEN_ICTL_PMA_SYNTHCKBYPASSEN_NT (1 << 13)
/**** IPD_MULTI_SYNTH register ****/
#define SERDES_GEN_IPD_MULTI_SYNTH_B (1 << 0)
/**** IRST register ****/
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A (1 << 0)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A (1 << 1)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A (1 << 2)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A (1 << 3)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A (1 << 4)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A (1 << 5)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A (1 << 6)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A (1 << 7)
#define SERDES_GEN_IRST_MULTI_HARD_SYNTH_B_A (1 << 8)
#define SERDES_GEN_IRST_POR_B_A (1 << 12)
#define SERDES_GEN_IRST_PIPE_RST_L3_B_A_SEL (1 << 16)
#define SERDES_GEN_IRST_PIPE_RST_L2_B_A_SEL (1 << 17)
#define SERDES_GEN_IRST_PIPE_RST_L1_B_A_SEL (1 << 18)
#define SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL (1 << 19)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L3_B_A_SEL (1 << 20)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L2_B_A_SEL (1 << 21)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L1_B_A_SEL (1 << 22)
#define SERDES_GEN_IRST_MULTI_HARD_TXRX_L0_B_A_SEL (1 << 23)
/**** OCTL_MULTI_SYNTHREADY register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHREADY_A (1 << 0)
/**** OCTL_MULTI_SYNTHSTATUS register ****/
#define SERDES_GEN_OCTL_MULTI_SYNTHSTATUS_A (1 << 0)
/**** clk_out register ****/
#define SERDES_GEN_CLK_OUT_SEL_MASK 0x0000003F
#define SERDES_GEN_CLK_OUT_SEL_SHIFT 0
/**** OCTL_PMA register ****/
#define SERDES_LANE_OCTL_PMA_TXSTATUS_L_A (1 << 0)
/**** ICTL_MULTI_ANDME register ****/
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A (1 << 0)
#define SERDES_LANE_ICTL_MULTI_ANDME_EN_L_A_SEL (1 << 1)
/**** ICTL_MULTI_LB register ****/
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXIOTIMEDEN_L_NT (1 << 0)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT (1 << 1)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT (1 << 2)
#define SERDES_LANE_ICTL_MULTI_LB_PARRX2TXTIMEDEN_L_NT (1 << 3)
#define SERDES_LANE_ICTL_MULTI_LB_CDRCLK2TXEN_L_NT (1 << 4)
#define SERDES_LANE_ICTL_MULTI_LB_TX2RXBUFTIMEDEN_L_NT_SEL (1 << 8)
#define SERDES_LANE_ICTL_MULTI_LB_RX2TXUNTIMEDEN_L_NT_SEL (1 << 9)
/**** ICTL_MULTI_RXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_RXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI_TXBIST register ****/
#define SERDES_LANE_ICTL_MULTI_TXBIST_EN_L_A (1 << 0)
/**** ICTL_MULTI register ****/
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_MASK 0x00000003
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_PSTATE_L_SEL (1 << 2)
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXDATAWIDTH_L_SHIFT 4
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATAEN_L_A (1 << 8)
#define SERDES_LANE_ICTL_MULTI_RXOVRCDRLOCK2DATA_L_A (1 << 9)
#define SERDES_LANE_ICTL_MULTI_TXBEACON_L_A (1 << 12)
#define SERDES_LANE_ICTL_MULTI_TXDETECTRXREQ_L_A (1 << 13)
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_MASK 0x00070000
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SHIFT 16
#define SERDES_LANE_ICTL_MULTI_RXRATE_L_SEL (1 << 19)
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_MASK 0x00700000
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SHIFT 20
#define SERDES_LANE_ICTL_MULTI_TXRATE_L_SEL (1 << 23)
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_MASK 0x07000000
#define SERDES_LANE_ICTL_MULTI_TXAMP_L_SHIFT 24
#define SERDES_LANE_ICTL_MULTI_TXAMP_EN_L (1 << 27)
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_MASK 0x70000000
#define SERDES_LANE_ICTL_MULTI_TXDATAWIDTH_L_SHIFT 28
/**** ICTL_MULTI_RXEQ register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_EN_L (1 << 0)
#define SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A (1 << 1)
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_MASK 0x00000070
#define SERDES_LANE_ICTL_MULTI_RXEQ_PRECAL_CODE_SEL_SHIFT 4
/**** ICTL_MULTI_RXEQ_L_high register ****/
#define SERDES_LANE_ICTL_MULTI_RXEQ_L_HIGH_VAL (1 << 0)
/**** ICTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_ICTL_MULTI_RXEYEDIAG_START_L_A (1 << 0)
/**** ICTL_MULTI_TXDEEMPH register ****/
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_MASK 0x0003FFFF
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_L_SHIFT 0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_MASK 0x7c0
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_ZERO_SHIFT 6
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_MASK 0xf000
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_PLUS_SHIFT 12
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_MASK 0x7
#define SERDES_LANE_ICTL_MULTI_TXDEEMPH_C_MINUS_SHIFT 0
/**** ICTL_MULTI_TXMARGIN register ****/
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_MASK 0x00000007
#define SERDES_LANE_ICTL_MULTI_TXMARGIN_L_SHIFT 0
/**** ICTL_MULTI_TXSWING register ****/
#define SERDES_LANE_ICTL_MULTI_TXSWING_L (1 << 0)
/**** IDAT_MULTI register ****/
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_MASK 0x0000000F
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SHIFT 0
#define SERDES_LANE_IDAT_MULTI_TXELECIDLE_L_SEL (1 << 4)
/**** IPD_MULTI register ****/
#define SERDES_LANE_IPD_MULTI_TX_L_B (1 << 0)
#define SERDES_LANE_IPD_MULTI_RX_L_B (1 << 1)
/**** OCTL_MULTI_RXBIST register ****/
#define SERDES_LANE_OCTL_MULTI_RXBIST_DONE_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXBIST_RXLOCKED_L_A (1 << 1)
/**** OCTL_MULTI register ****/
#define SERDES_LANE_OCTL_MULTI_RXCDRLOCK2DATA_L_A (1 << 0)
#define SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A (1 << 1)
#define SERDES_LANE_OCTL_MULTI_RXREADY_L_A (1 << 2)
#define SERDES_LANE_OCTL_MULTI_RXSTATUS_L_A (1 << 3)
#define SERDES_LANE_OCTL_MULTI_TXREADY_L_A (1 << 4)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXSTAT_L_A (1 << 5)
#define SERDES_LANE_OCTL_MULTI_TXDETECTRXACK_L_A (1 << 6)
#define SERDES_LANE_OCTL_MULTI_RXSIGNALDETECT_L_A (1 << 7)
/**** OCTL_MULTI_RXEYEDIAG register ****/
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_MASK 0x00003FFF
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_STAT_L_A_SHIFT 0
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_DONE_L_A (1 << 16)
#define SERDES_LANE_OCTL_MULTI_RXEYEDIAG_ERR_L_A (1 << 17)
/**** ODAT_MULTI_RXBIST register ****/
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_MASK 0x0000FFFF
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_L_A_SHIFT 0
#define SERDES_LANE_ODAT_MULTI_RXBIST_ERRCOUNT_OVERFLOW_L_A (1 << 16)
/**** ODAT_MULTI_RXEQ register ****/
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_MASK 0x00003FFF
#define SERDES_LANE_ODAT_MULTI_RXEQ_BEST_EYE_VAL_L_A_SHIFT 0
/**** MULTI_RX_DVALID register ****/
#define SERDES_LANE_MULTI_RX_DVALID_MASK_CDR_LOCK (1 << 0)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SIGNALDETECT (1 << 1)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_TX_READY (1 << 2)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_READY (1 << 3)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_SYNT_READY (1 << 4)
#define SERDES_LANE_MULTI_RX_DVALID_MASK_RX_ELECIDLE (1 << 5)
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_MASK 0x00FF0000
#define SERDES_LANE_MULTI_RX_DVALID_MUX_SEL_SHIFT 16
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_SEL (1 << 24)
#define SERDES_LANE_MULTI_RX_DVALID_PS_00_VAL (1 << 25)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_SEL (1 << 26)
#define SERDES_LANE_MULTI_RX_DVALID_PS_01_VAL (1 << 27)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_SEL (1 << 28)
#define SERDES_LANE_MULTI_RX_DVALID_PS_10_VAL (1 << 29)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_SEL (1 << 30)
#define SERDES_LANE_MULTI_RX_DVALID_PS_11_VAL (1 << 31)
/**** reserved register ****/
#define SERDES_LANE_RESERVED_OUT_MASK 0x000000FF
#define SERDES_LANE_RESERVED_OUT_SHIFT 0
#define SERDES_LANE_RESERVED_IN_MASK 0x00FF0000
#define SERDES_LANE_RESERVED_IN_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_serdes_REGS_H__ */
/** @} end of ... group */

View File

@ -0,0 +1,117 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* @{
* @file al_hal_types.h
*
* @brief macros used by HALs and platform layer
*
*/
#ifndef __AL_HAL_TYPES_H__
#define __AL_HAL_TYPES_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* Common defines */
#if (!AL_TRUE) || (AL_FALSE)
#error "AL_TRUE must be non zero and AL_FALSE must be zero"
#endif
typedef int AL_RETURN;
#if !defined(NULL)
#define NULL (void *)0
#endif
#if !defined(likely)
#define likely(x) (__builtin_expect(!!(x), 1))
#define unlikely(x) (__builtin_expect(!!(x), 0))
#endif
#ifdef __GNUC__
#if !defined(__packed)
#define __packed __attribute__ ((packed))
#endif
/* packed and alinged types */
#define __packed_a4 __attribute__ ((packed, aligned(4)))
#define __packed_a8 __attribute__ ((packed, aligned(8)))
#define __packed_a16 __attribute__ ((packed, aligned(16)))
#else
#if !defined(__packed)
#error "__packed is not defined!!"
#endif
#endif
#if !defined(__iomem)
#define __iomem
#endif
#if !defined(__cache_aligned)
#ifdef __GNUC__
#define __cache_aligned __attribute__ ((__aligned__(64)))
#else
#define __cache_aligned
#endif
#endif
#if !defined(INLINE)
#ifdef __GNUC__
#define INLINE inline
#else
#define INLINE
#endif
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Common group */
#endif /* __TYPES_H__ */

View File

@ -0,0 +1,672 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_udma_api API
* @ingroup group_udma
* UDMA API
* @{
* @}
*
* @defgroup group_udma_main UDMA Main
* @ingroup group_udma_api
* UDMA main API
* @{
* @file al_hal_udma.h
*
* @brief C Header file for the Universal DMA HAL driver
*
*/
#ifndef __AL_HAL_UDMA_H__
#define __AL_HAL_UDMA_H__
#include "al_hal_common.h"
#include "al_hal_udma_regs.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#define DMA_MAX_Q 4
#define AL_UDMA_MIN_Q_SIZE 4
#define AL_UDMA_MAX_Q_SIZE (1 << 16) /* hw can do more, but we limit it */
/* Default Max number of descriptors supported per action */
#define AL_UDMA_DEFAULT_MAX_ACTN_DESCS 16
#define AL_UDMA_REV_ID_0 0
#define AL_UDMA_REV_ID_1 1
#define AL_UDMA_REV_ID_2 2
#define DMA_RING_ID_MASK 0x3
/* New registers ?? */
/* Statistics - TBD */
/** UDMA submission descriptor */
union al_udma_desc {
/* TX */
struct {
uint32_t len_ctrl;
uint32_t meta_ctrl;
uint64_t buf_ptr;
} tx;
/* TX Meta, used by upper layer */
struct {
uint32_t len_ctrl;
uint32_t meta_ctrl;
uint32_t meta1;
uint32_t meta2;
} tx_meta;
/* RX */
struct {
uint32_t len_ctrl;
uint32_t buf2_ptr_lo;
uint64_t buf1_ptr;
} rx;
} __packed_a16;
/* TX desc length and control fields */
#define AL_M2S_DESC_CONCAT AL_BIT(31) /* concatenate */
#define AL_M2S_DESC_DMB AL_BIT(30)
/** Data Memory Barrier */
#define AL_M2S_DESC_NO_SNOOP_H AL_BIT(29)
#define AL_M2S_DESC_INT_EN AL_BIT(28) /** enable interrupt */
#define AL_M2S_DESC_LAST AL_BIT(27)
#define AL_M2S_DESC_FIRST AL_BIT(26)
#define AL_M2S_DESC_RING_ID_SHIFT 24
#define AL_M2S_DESC_RING_ID_MASK (0x3 << AL_M2S_DESC_RING_ID_SHIFT)
#define AL_M2S_DESC_META_DATA AL_BIT(23)
#define AL_M2S_DESC_DUMMY AL_BIT(22) /* for Metdata only */
#define AL_M2S_DESC_LEN_ADJ_SHIFT 20
#define AL_M2S_DESC_LEN_ADJ_MASK (0x7 << AL_M2S_DESC_LEN_ADJ_SHIFT)
#define AL_M2S_DESC_LEN_SHIFT 0
#define AL_M2S_DESC_LEN_MASK (0xfffff << AL_M2S_DESC_LEN_SHIFT)
#define AL_S2M_DESC_DUAL_BUF AL_BIT(31)
#define AL_S2M_DESC_NO_SNOOP_H AL_BIT(29)
#define AL_S2M_DESC_INT_EN AL_BIT(28) /** enable interrupt */
#define AL_S2M_DESC_RING_ID_SHIFT 24
#define AL_S2M_DESC_RING_ID_MASK (0x3 << AL_S2M_DESC_RING_ID_SHIFT)
#define AL_S2M_DESC_LEN_SHIFT 0
#define AL_S2M_DESC_LEN_MASK (0xffff << AL_S2M_DESC_LEN_SHIFT)
#define AL_S2M_DESC_LEN2_SHIFT 16
#define AL_S2M_DESC_LEN2_MASK (0x3fff << AL_S2M_DESC_LEN2_SHIFT)
#define AL_S2M_DESC_LEN2_GRANULARITY_SHIFT 6
/* TX/RX descriptor VMID field (in the buffer address 64 bit field) */
#define AL_UDMA_DESC_VMID_SHIFT 48
/** UDMA completion descriptor */
union al_udma_cdesc {
/* TX completion */
struct {
uint32_t ctrl_meta;
} al_desc_comp_tx;
/* RX completion */
struct {
/* TBD */
uint32_t ctrl_meta;
} al_desc_comp_rx;
} __packed_a4;
/* TX/RX common completion desc ctrl_meta feilds */
#define AL_UDMA_CDESC_ERROR AL_BIT(31)
#define AL_UDMA_CDESC_BUF1_USED AL_BIT(30)
#define AL_UDMA_CDESC_DDP AL_BIT(29)
#define AL_UDMA_CDESC_LAST AL_BIT(27)
#define AL_UDMA_CDESC_FIRST AL_BIT(26)
/* word 2 */
#define AL_UDMA_CDESC_BUF2_USED AL_BIT(31)
#define AL_UDMA_CDESC_BUF2_LEN_SHIFT 16
#define AL_UDMA_CDESC_BUF2_LEN_MASK AL_FIELD_MASK(29, 16)
/** Basic Buffer structure */
struct al_buf {
al_phys_addr_t addr; /**< Buffer physical address */
uint32_t len; /**< Buffer lenght in bytes */
};
/** Block is a set of buffers that belong to same source or destination */
struct al_block {
struct al_buf *bufs; /**< The buffers of the block */
uint32_t num; /**< Number of buffers of the block */
/**<
* VMID to be assigned to the block descriptors
* Requires VMID in descriptor to be enabled for the specific UDMA
* queue.
*/
uint16_t vmid;
};
/** UDMA type */
enum al_udma_type {
UDMA_TX,
UDMA_RX
};
/** UDMA state */
enum al_udma_state {
UDMA_DISABLE = 0,
UDMA_IDLE,
UDMA_NORMAL,
UDMA_ABORT,
UDMA_RESET
};
extern const char *const al_udma_states_name[];
/** UDMA Q specific parameters from upper layer */
struct al_udma_q_params {
uint32_t size; /**< ring size (in descriptors), submission and
* completion rings must have same size
*/
union al_udma_desc *desc_base; /**< cpu address for submission ring
* descriptors
*/
al_phys_addr_t desc_phy_base; /**< submission ring descriptors
* physical base address
*/
#ifdef __FreeBSD__
bus_dma_tag_t desc_phy_base_tag;
bus_dmamap_t desc_phy_base_map;
#endif
uint8_t *cdesc_base; /**< completion descriptors pointer, NULL */
/* means no completion update */
al_phys_addr_t cdesc_phy_base; /**< completion descriptors ring
* physical base address
*/
#ifdef __FreeBSD__
bus_dma_tag_t cdesc_phy_base_tag;
bus_dmamap_t cdesc_phy_base_map;
#endif
uint32_t cdesc_size; /**< size (in bytes) of a single dma completion
* descriptor
*/
uint8_t adapter_rev_id; /**<PCI adapter revision ID */
};
/** UDMA parameters from upper layer */
struct al_udma_params {
struct unit_regs __iomem *udma_regs_base;
enum al_udma_type type; /**< Tx or Rx */
uint8_t num_of_queues; /**< number of queues supported by the UDMA */
const char *name; /**< the upper layer must keep the string area */
};
/* Fordward decleration */
struct al_udma;
/** SW status of a queue */
enum al_udma_queue_status {
AL_QUEUE_NOT_INITIALIZED = 0,
AL_QUEUE_DISABLED,
AL_QUEUE_ENABLED,
AL_QUEUE_ABORTED
};
/** UDMA Queue private data structure */
struct __cache_aligned al_udma_q {
uint16_t size_mask; /**< mask used for pointers wrap around
* equals to size - 1
*/
union udma_q_regs __iomem *q_regs; /**< pointer to the per queue UDMA
* registers
*/
union al_udma_desc *desc_base_ptr; /**< base address submission ring
* descriptors
*/
uint16_t next_desc_idx; /**< index to the next available submission
* descriptor
*/
uint32_t desc_ring_id; /**< current submission ring id */
uint8_t *cdesc_base_ptr;/**< completion descriptors pointer, NULL */
/* means no completion */
uint32_t cdesc_size; /**< size (in bytes) of the udma completion ring
* descriptor
*/
uint16_t next_cdesc_idx; /**< index in descriptors for next completing
* ring descriptor
*/
uint8_t *end_cdesc_ptr; /**< used for wrap around detection */
uint16_t comp_head_idx; /**< completion ring head pointer register
*shadow
*/
volatile union al_udma_cdesc *comp_head_ptr; /**< when working in get_packet mode
* we maintain pointer instead of the
* above idx
*/
uint32_t pkt_crnt_descs; /**< holds the number of processed descriptors
* of the current packet
*/
uint32_t comp_ring_id; /**< current completion Ring Id */
al_phys_addr_t desc_phy_base; /**< submission desc. physical base */
al_phys_addr_t cdesc_phy_base; /**< completion desc. physical base */
uint32_t flags; /**< flags used for completion modes */
uint32_t size; /**< ring size in descriptors */
enum al_udma_queue_status status;
struct al_udma *udma; /**< pointer to parent UDMA */
uint32_t qid; /**< the index number of the queue */
/*
* The following fields are duplicated from the UDMA parent adapter
* due to performance considerations.
*/
uint8_t adapter_rev_id; /**<PCI adapter revision ID */
};
/* UDMA */
struct al_udma {
const char *name;
enum al_udma_type type; /* Tx or Rx */
enum al_udma_state state;
uint8_t num_of_queues; /* number of queues supported by the UDMA */
union udma_regs __iomem *udma_regs; /* pointer to the UDMA registers */
struct udma_gen_regs *gen_regs; /* pointer to the Gen registers*/
struct al_udma_q udma_q[DMA_MAX_Q]; /* Array of UDMA Qs pointers */
unsigned int rev_id; /* UDMA revision ID */
};
/*
* Configurations
*/
/* Initializations functions */
/**
* Initialize the udma engine
*
* @param udma udma data structure
* @param udma_params udma parameters from upper layer
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_udma_init(struct al_udma *udma, struct al_udma_params *udma_params);
/**
* Initialize the udma queue data structure
*
* @param udma
* @param qid
* @param q_params
*
* @return 0 if no error found.
* -EINVAL if the qid is out of range
* -EIO if queue was already initialized
*/
int al_udma_q_init(struct al_udma *udma, uint32_t qid,
struct al_udma_q_params *q_params);
/**
* Reset a udma queue
*
* Prior to calling this function make sure:
* 1. Queue interrupts are masked
* 2. No additional descriptors are written to the descriptor ring of the queue
* 3. No completed descriptors are being fetched
*
* The queue can be initialized again using 'al_udma_q_init'
*
* @param udma_q
*
* @return 0 if no error found.
*/
int al_udma_q_reset(struct al_udma_q *udma_q);
/**
* return (by reference) a pointer to a specific queue date structure.
* this pointer needed for calling functions (i.e. al_udma_desc_action_add) that
* require this pointer as input argument.
*
* @param udma udma data structure
* @param qid queue index
* @param q_handle pointer to the location where the queue structure pointer
* written to.
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_udma_q_handle_get(struct al_udma *udma, uint32_t qid,
struct al_udma_q **q_handle);
/**
* Change the UDMA's state
*
* @param udma udma data structure
* @param state the target state
*
* @return 0
*/
int al_udma_state_set(struct al_udma *udma, enum al_udma_state state);
/**
* return the current UDMA hardware state
*
* @param udma udma handle
*
* @return the UDMA state as reported by the hardware.
*/
enum al_udma_state al_udma_state_get(struct al_udma *udma);
/*
* Action handling
*/
/**
* get number of descriptors that can be submitted to the udma.
* keep one free descriptor to simplify full/empty management
* @param udma_q queue handle
*
* @return num of free descriptors.
*/
static INLINE uint32_t al_udma_available_get(struct al_udma_q *udma_q)
{
uint16_t tmp = udma_q->next_cdesc_idx - (udma_q->next_desc_idx + 1);
tmp &= udma_q->size_mask;
return (uint32_t) tmp;
}
/**
* check if queue has pending descriptors
*
* @param udma_q queue handle
*
* @return AL_TRUE if descriptors are submitted to completion ring and still
* not completed (with ack). AL_FALSE otherwise.
*/
static INLINE al_bool al_udma_is_empty(struct al_udma_q *udma_q)
{
if (((udma_q->next_cdesc_idx - udma_q->next_desc_idx) &
udma_q->size_mask) == 0)
return AL_TRUE;
return AL_FALSE;
}
/**
* get next available descriptor
* @param udma_q queue handle
*
* @return pointer to the next available descriptor
*/
static INLINE union al_udma_desc *al_udma_desc_get(struct al_udma_q *udma_q)
{
union al_udma_desc *desc;
uint16_t next_desc_idx;
al_assert(udma_q);
next_desc_idx = udma_q->next_desc_idx;
desc = udma_q->desc_base_ptr + next_desc_idx;
next_desc_idx++;
/* if reached end of queue, wrap around */
udma_q->next_desc_idx = next_desc_idx & udma_q->size_mask;
return desc;
}
/**
* get ring id for the last allocated descriptor
* @param udma_q
*
* @return ring id for the last allocated descriptor
* this function must be called each time a new descriptor is allocated
* by the al_udma_desc_get(), unless ring id is ignored.
*/
static INLINE uint32_t al_udma_ring_id_get(struct al_udma_q *udma_q)
{
uint32_t ring_id;
al_assert(udma_q);
ring_id = udma_q->desc_ring_id;
/* calculate the ring id of the next desc */
/* if next_desc points to first desc, then queue wrapped around */
if (unlikely(udma_q->next_desc_idx) == 0)
udma_q->desc_ring_id = (udma_q->desc_ring_id + 1) &
DMA_RING_ID_MASK;
return ring_id;
}
/* add DMA action - trigger the engine */
/**
* add num descriptors to the submission queue.
*
* @param udma_q queue handle
* @param num number of descriptors to add to the queues ring.
*
* @return 0;
*/
static INLINE int al_udma_desc_action_add(struct al_udma_q *udma_q,
uint32_t num)
{
uint32_t *addr;
al_assert(udma_q);
al_assert((num > 0) && (num <= udma_q->size));
addr = &udma_q->q_regs->rings.drtp_inc;
/* make sure data written to the descriptors will be visible by the */
/* DMA */
al_local_data_memory_barrier();
/*
* As we explicitly invoke the synchronization function
* (al_data_memory_barrier()), then we can use the relaxed version.
*/
al_reg_write32_relaxed(addr, num);
return 0;
}
#define cdesc_is_first(flags) ((flags) & AL_UDMA_CDESC_FIRST)
#define cdesc_is_last(flags) ((flags) & AL_UDMA_CDESC_LAST)
/**
* return pointer to the cdesc + offset desciptors. wrap around when needed.
*
* @param udma_q queue handle
* @param cdesc pointer that set by this function
* @param offset offset desciptors
*
*/
static INLINE volatile union al_udma_cdesc *al_cdesc_next(
struct al_udma_q *udma_q,
volatile union al_udma_cdesc *cdesc,
uint32_t offset)
{
volatile uint8_t *tmp = (volatile uint8_t *) cdesc + offset * udma_q->cdesc_size;
al_assert(udma_q);
al_assert(cdesc);
/* if wrap around */
if (unlikely((tmp > udma_q->end_cdesc_ptr)))
return (union al_udma_cdesc *)
(udma_q->cdesc_base_ptr +
(tmp - udma_q->end_cdesc_ptr - udma_q->cdesc_size));
return (volatile union al_udma_cdesc *) tmp;
}
/**
* check if the flags of the descriptor indicates that is new one
* the function uses the ring id from the descriptor flags to know whether it
* new one by comparing it with the curring ring id of the queue
*
* @param udma_q queue handle
* @param flags the flags of the completion descriptor
*
* @return AL_TRUE if the completion descriptor is new one.
* AL_FALSE if it old one.
*/
static INLINE al_bool al_udma_new_cdesc(struct al_udma_q *udma_q,
uint32_t flags)
{
if (((flags & AL_M2S_DESC_RING_ID_MASK) >> AL_M2S_DESC_RING_ID_SHIFT)
== udma_q->comp_ring_id)
return AL_TRUE;
return AL_FALSE;
}
/**
* get next completion descriptor
* this function will also increment the completion ring id when the ring wraps
* around
*
* @param udma_q queue handle
* @param cdesc current completion descriptor
*
* @return pointer to the completion descriptor that follows the one pointed by
* cdesc
*/
static INLINE volatile union al_udma_cdesc *al_cdesc_next_update(
struct al_udma_q *udma_q,
volatile union al_udma_cdesc *cdesc)
{
/* if last desc, wrap around */
if (unlikely(((volatile uint8_t *) cdesc == udma_q->end_cdesc_ptr))) {
udma_q->comp_ring_id =
(udma_q->comp_ring_id + 1) & DMA_RING_ID_MASK;
return (union al_udma_cdesc *) udma_q->cdesc_base_ptr;
}
return (volatile union al_udma_cdesc *) ((volatile uint8_t *) cdesc + udma_q->cdesc_size);
}
/**
* get next completed packet from completion ring of the queue
*
* @param udma_q udma queue handle
* @param desc pointer that set by this function to the first descriptor
* note: desc is valid only when return value is not zero
* @return number of descriptors that belong to the packet. 0 means no completed
* full packet was found.
* If the descriptors found in the completion queue don't form full packet (no
* desc with LAST flag), then this function will do the following:
* (1) save the number of processed descriptors.
* (2) save last processed descriptor, so next time it called, it will resume
* from there.
* (3) return 0.
* note: the descriptors that belong to the completed packet will still be
* considered as used, that means the upper layer is safe to access those
* descriptors when this function returns. the al_udma_cdesc_ack() should be
* called to inform the udma driver that those descriptors are freed.
*/
uint32_t al_udma_cdesc_packet_get(
struct al_udma_q *udma_q,
volatile union al_udma_cdesc **desc);
/** get completion descriptor pointer from its index */
#define al_udma_cdesc_idx_to_ptr(udma_q, idx) \
((volatile union al_udma_cdesc *) ((udma_q)->cdesc_base_ptr + \
(idx) * (udma_q)->cdesc_size))
/**
* return number of all completed descriptors in the completion ring
*
* @param udma_q udma queue handle
* @param cdesc pointer that set by this function to the first descriptor
* note: desc is valid only when return value is not zero
* note: pass NULL if not interested
* @return number of descriptors. 0 means no completed descriptors were found.
* note: the descriptors that belong to the completed packet will still be
* considered as used, that means the upper layer is safe to access those
* descriptors when this function returns. the al_udma_cdesc_ack() should be
* called to inform the udma driver that those descriptors are freed.
*/
static INLINE uint32_t al_udma_cdesc_get_all(
struct al_udma_q *udma_q,
volatile union al_udma_cdesc **cdesc)
{
uint16_t count = 0;
al_assert(udma_q);
udma_q->comp_head_idx = (uint16_t)
(al_reg_read32(&udma_q->q_regs->rings.crhp) &
0xFFFF);
count = (udma_q->comp_head_idx - udma_q->next_cdesc_idx) &
udma_q->size_mask;
if (cdesc)
*cdesc = al_udma_cdesc_idx_to_ptr(udma_q, udma_q->next_cdesc_idx);
return (uint32_t)count;
}
/**
* acknowledge the driver that the upper layer completed processing completion
* descriptors
*
* @param udma_q udma queue handle
* @param num number of descriptors to acknowledge
*
* @return 0
*/
static INLINE int al_udma_cdesc_ack(struct al_udma_q *udma_q, uint32_t num)
{
al_assert(udma_q);
udma_q->next_cdesc_idx += num;
udma_q->next_cdesc_idx &= udma_q->size_mask;
return 0;
}
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_HAL_UDMA_H__ */
/** @} end of UDMA group */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,755 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_udma_config UDMA Config
* @ingroup group_udma_api
* UDMA Config API
* @{
* @file al_hal_udma_config.h
*
* @brief C Header file for the Universal DMA HAL driver for configuration APIs
*
*/
#ifndef __AL_HAL_UDMA_CONFIG_H__
#define __AL_HAL_UDMA_CONFIG_H__
#include <al_hal_udma.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/** Scheduling mode */
enum al_udma_sch_mode {
STRICT, /* Strict */
SRR, /* Simple Sound Rubin */
DWRR /* Deficit Weighted Round Rubin */
};
/** AXI configuration */
struct al_udma_axi_conf {
uint32_t axi_timeout; /* Timeout for AXI transactions */
uint8_t arb_promotion; /* arbitration promotion */
al_bool swap_8_bytes; /* enable 8 bytes swap instead of 4 bytes */
al_bool swap_s2m_data;
al_bool swap_s2m_desc;
al_bool swap_m2s_data;
al_bool swap_m2s_desc;
};
/** UDMA AXI M2S configuration */
struct al_udma_axi_submaster {
uint8_t id; /* AXI ID */
uint8_t cache_type;
uint8_t burst;
uint16_t used_ext;
uint8_t bus_size;
uint8_t qos;
uint8_t prot;
uint8_t max_beats;
};
/** UDMA AXI M2S configuration */
struct al_udma_m2s_axi_conf {
struct al_udma_axi_submaster comp_write;
struct al_udma_axi_submaster data_read;
struct al_udma_axi_submaster desc_read;
al_bool break_on_max_boundary; /* Data read break on max boundary */
uint8_t min_axi_beats; /* Minimum burst for writing completion desc. */
uint8_t ostand_max_data_read;
uint8_t ostand_max_desc_read;
uint8_t ostand_max_comp_req;
uint8_t ostand_max_comp_write;
};
/** UDMA AXI S2M configuration */
struct al_udma_s2m_axi_conf {
struct al_udma_axi_submaster data_write;
struct al_udma_axi_submaster desc_read;
struct al_udma_axi_submaster comp_write;
al_bool break_on_max_boundary; /* Data read break on max boundary */
uint8_t min_axi_beats; /* Minimum burst for writing completion desc. */
uint8_t ostand_max_data_req;
uint8_t ostand_max_data_write;
uint8_t ostand_max_comp_req;
uint8_t ostand_max_comp_write;
uint8_t ostand_max_desc_read;
uint8_t ack_fifo_depth; /* size of the stream application ack fifo */
};
/** M2S error logging */
struct al_udma_err_log {
uint32_t error_status;
uint32_t header[4];
};
/** M2S max packet size configuration */
struct al_udma_m2s_pkt_len_conf {
uint32_t max_pkt_size;
al_bool encode_64k_as_zero;
};
/** M2S Descriptor Prefetch configuration */
struct al_udma_m2s_desc_pref_conf {
uint8_t desc_fifo_depth;
enum al_udma_sch_mode sch_mode; /* Scheduling mode
* (either strict or RR) */
uint8_t max_desc_per_packet; /* max number of descriptors to
* prefetch */
/* in one burst (5b) */
uint8_t pref_thr;
uint8_t min_burst_above_thr; /* min burst size when fifo above
* pref_thr (4b)
*/
uint8_t min_burst_below_thr; /* min burst size when fifo below
* pref_thr (4b)
*/
uint8_t max_pkt_limit; /* maximum number of packets in the data
* read FIFO, defined based on header
* FIFO size
*/
uint16_t data_fifo_depth; /* maximum number of data beats in the
* data read FIFO,
* defined based on header FIFO size
*/
};
/** S2M Descriptor Prefetch configuration */
struct al_udma_s2m_desc_pref_conf {
uint8_t desc_fifo_depth;
enum al_udma_sch_mode sch_mode; /* Scheduling mode *
* (either strict or RR)
*/
al_bool q_promotion; /* enable promotion */
al_bool force_promotion; /* force promotion */
al_bool en_pref_prediction; /* enable prefetch prediction */
uint8_t promotion_th; /* Threshold for queue promotion */
uint8_t pref_thr;
uint8_t min_burst_above_thr; /* min burst size when fifo above
* pref_thr (4b)
*/
uint8_t min_burst_below_thr; /* min burst size when fifo below
* pref_thr (4b)
*/
uint8_t a_full_thr; /* almost full threshold */
};
/** S2M Data write configuration */
struct al_udma_s2m_data_write_conf {
uint16_t data_fifo_depth; /* maximum number of data beats in the
* data write FIFO, defined based on
* header FIFO size
*/
uint8_t max_pkt_limit; /* maximum number of packets in the
* data write FIFO,defined based on
* header FIFO size
*/
uint8_t fifo_margin;
uint32_t desc_wait_timer; /* waiting time for the host to write
* new descriptor to the queue
* (for the current packet in process)
*/
uint32_t flags; /* bitwise of flags of s2m
* data_cfg_2 register
*/
};
/** S2M Completion configuration */
struct al_udma_s2m_completion_conf {
uint8_t desc_size; /* Size of completion descriptor
* in words
*/
al_bool cnt_words; /* Completion fifo in use counter:
* AL_TRUE words, AL_FALS descriptors
*/
al_bool q_promotion; /* Enable promotion of the current
* unack in progress */
/* in the completion write scheduler */
al_bool force_rr; /* force RR arbitration in the
* scheduler
*/
// uint8_t ack_fifo_depth; /* size of the stream application ack fifo */
uint8_t q_free_min; /* minimum number of free completion
* entries
*/
/* to qualify for promotion */
uint16_t comp_fifo_depth; /* Size of completion fifo in words */
uint16_t unack_fifo_depth; /* Size of unacked fifo in descs */
uint32_t timeout; /* Ack timout from stream interface */
};
/** M2S UDMA DWRR configuration */
struct al_udma_m2s_dwrr_conf {
al_bool enable_dwrr;
uint8_t inc_factor;
uint8_t weight;
al_bool pkt_mode;
uint32_t deficit_init_val;
};
/** M2S DMA Rate Limitation mode */
struct al_udma_m2s_rlimit_mode {
al_bool pkt_mode_en;
uint16_t short_cycle_sz;
uint32_t token_init_val;
};
/** M2S Stream/Q Rate Limitation */
struct al_udma_m2s_rlimit_cfg {
uint32_t max_burst_sz; /* maximum number of accumulated bytes in the
* token counter
*/
uint16_t long_cycle_sz; /* number of short cycles between token fill */
uint32_t long_cycle; /* number of bits to add in each long cycle */
uint32_t short_cycle; /* number of bits to add in each cycle */
uint32_t mask; /* mask the different types of rate limiters */
};
enum al_udma_m2s_rlimit_action {
AL_UDMA_STRM_RLIMIT_ENABLE,
AL_UDMA_STRM_RLIMIT_PAUSE,
AL_UDMA_STRM_RLIMIT_RESET
};
/** M2S UDMA Q scheduling configuration */
struct al_udma_m2s_q_dwrr_conf {
uint32_t max_deficit_cnt_sz; /*maximum number of accumulated bytes
* in the deficit counter
*/
al_bool strict; /* bypass DWRR */
uint8_t axi_qos;
uint16_t q_qos;
uint8_t weight;
};
/** M2S UDMA / UDMA Q scheduling configuration */
struct al_udma_m2s_sc {
enum al_udma_sch_mode sch_mode; /* Scheduling Mode */
struct al_udma_m2s_dwrr_conf dwrr; /* DWRR configuration */
};
/** UDMA / UDMA Q rate limitation configuration */
struct al_udma_m2s_rlimit {
struct al_udma_m2s_rlimit_mode rlimit_mode;
/* rate limitation enablers */
#if 0
struct al_udma_tkn_bkt_conf token_bkt; /* Token Bucket configuration */
#endif
};
/** UDMA Data read configuration */
struct al_udma_m2s_data_rd_conf {
uint8_t max_rd_d_beats; /* max burst size for reading data
* (in AXI beats-128b) (5b)
*/
uint8_t max_rd_d_out_req; /* max number of outstanding data
* read requests (6b)
*/
uint16_t max_rd_d_out_beats; /* max num. of data read beats (10b) */
};
/** M2S UDMA completion and application timeouts */
struct al_udma_m2s_comp_timeouts {
enum al_udma_sch_mode sch_mode; /* Scheduling mode
* (either strict or RR)
*/
al_bool enable_q_promotion;
uint8_t unack_fifo_depth; /* unacked desc fifo size */
uint8_t comp_fifo_depth; /* desc fifo size */
uint32_t coal_timeout; /* (24b) */
uint32_t app_timeout; /* (24b) */
};
/** S2M UDMA per queue completion configuration */
struct al_udma_s2m_q_comp_conf {
al_bool dis_comp_coal; /* disable completion coalescing */
al_bool en_comp_ring_update; /* enable writing completion descs */
uint32_t comp_timer; /* completion coalescing timer */
al_bool en_hdr_split; /* enable header split */
al_bool force_hdr_split; /* force header split */
uint16_t hdr_split_size; /* size used for the header split */
uint8_t q_qos; /* queue QoS */
};
/** UDMA per queue VMID control configuration */
struct al_udma_gen_vmid_q_conf {
/* Enable usage of the VMID per queue according to 'vmid' */
al_bool queue_en;
/* Enable usage of the VMID from the descriptor buffer address 63:48 */
al_bool desc_en;
/* VMID to be applied when 'queue_en' is asserted */
uint16_t vmid;
/* VMADDR to be applied to msbs when 'desc_en' is asserted.
* Relevant for revisions >= AL_UDMA_REV_ID_REV2 */
uint16_t vmaddr;
};
/** UDMA VMID control configuration */
struct al_udma_gen_vmid_conf {
/* TX queue configuration */
struct al_udma_gen_vmid_q_conf tx_q_conf[DMA_MAX_Q];
/* RX queue configuration */
struct al_udma_gen_vmid_q_conf rx_q_conf[DMA_MAX_Q];
};
/** UDMA VMID MSIX control configuration */
struct al_udma_gen_vmid_msix_conf {
/* Enable write to all VMID_n registers in the MSI-X Controller */
al_bool access_en;
/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */
al_bool sel;
};
/** UDMA per Tx queue advanced VMID control configuration */
struct al_udma_gen_vmid_advanced_tx_q_conf {
/**********************************************************************
* Tx Data VMID
**********************************************************************/
/* Tx data VMID enable */
al_bool tx_q_data_vmid_en;
/*
* For Tx data reads, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'tx_q_addr_hi_sel'
*/
unsigned int tx_q_addr_hi;
/*
* For Tx data reads, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
* When 'tx_q_addr_hi_sel'=32 all of 'tx_q_addr_hi' will be taken.
* When 'tx_q_addr_hi_sel'=0 none of it will be taken, and when any
* value in between, it will start from the MSB bit and sweep down as
* many bits as needed. For example if 'tx_q_addr_hi_sel'=8, the final
* address [63:56] will carry 'tx_q_addr_hi'[31:24] while [55:32] will
* carry the original buffer address[55:32].
*/
unsigned int tx_q_addr_hi_sel;
/*
* Tx data read VMID
* Masked per bit with 'tx_q_data_vmid_mask'
*/
unsigned int tx_q_data_vmid;
/*
* Tx data read VMID mask
* Each '1' selects from the buffer address, each '0' selects from
* 'tx_q_data_vmid'
*/
unsigned int tx_q_data_vmid_mask;
/**********************************************************************
* Tx prefetch VMID
**********************************************************************/
/* Tx prefetch VMID enable */
al_bool tx_q_prefetch_vmid_en;
/* Tx prefetch VMID */
unsigned int tx_q_prefetch_vmid;
/**********************************************************************
* Tx completion VMID
**********************************************************************/
/* Tx completion VMID enable */
al_bool tx_q_compl_vmid_en;
/* Tx completion VMID */
unsigned int tx_q_compl_vmid;
};
/** UDMA per Rx queue advanced VMID control configuration */
struct al_udma_gen_vmid_advanced_rx_q_conf {
/**********************************************************************
* Rx Data VMID
**********************************************************************/
/* Rx data VMID enable */
al_bool rx_q_data_vmid_en;
/*
* For Rx data writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_addr_hi_sel'
*/
unsigned int rx_q_addr_hi;
/*
* For Rx data writes, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
*/
unsigned int rx_q_addr_hi_sel;
/*
* Rx data write VMID
* Masked per bit with 'rx_q_data_vmid_mask'
*/
unsigned int rx_q_data_vmid;
/* Rx data write VMID mask */
unsigned int rx_q_data_vmid_mask;
/**********************************************************************
* Rx Data Buffer 2 VMID
**********************************************************************/
/* Rx data buff2 VMID enable */
al_bool rx_q_data_buff2_vmid_en;
/*
* For Rx data buff2 writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_data_buff2_addr_hi_sel'
*/
unsigned int rx_q_data_buff2_addr_hi;
/*
* For Rx data buff2 writes, 6 bits serving the number of bits taken
* from the extra register on account of bits coming from the original
* address field.
*/
unsigned int rx_q_data_buff2_addr_hi_sel;
/*
* Rx data buff2 write VMID
* Masked per bit with 'rx_q_data_buff2_mask'
*/
unsigned int rx_q_data_buff2_vmid;
/* Rx data buff2 write VMID mask */
unsigned int rx_q_data_buff2_mask;
/**********************************************************************
* Rx DDP VMID
**********************************************************************/
/* Rx DDP write VMID enable */
al_bool rx_q_ddp_vmid_en;
/*
* For Rx DDP writes, replacement bits for the original address.
* The number of bits replaced is determined according to
* 'rx_q_ddp_addr_hi_sel'
*/
unsigned int rx_q_ddp_addr_hi;
/*
* For Rx DDP writes, 6 bits serving the number of bits taken from the
* extra register on account of bits coming from the original address
* field.
*/
unsigned int rx_q_ddp_addr_hi_sel;
/*
* Rx DDP write VMID
* Masked per bit with 'rx_q_ddp_mask'
*/
unsigned int rx_q_ddp_vmid;
/* Rx DDP write VMID mask */
unsigned int rx_q_ddp_mask;
/**********************************************************************
* Rx prefetch VMID
**********************************************************************/
/* Rx prefetch VMID enable */
al_bool rx_q_prefetch_vmid_en;
/* Rx prefetch VMID */
unsigned int rx_q_prefetch_vmid;
/**********************************************************************
* Rx completion VMID
**********************************************************************/
/* Rx completion VMID enable */
al_bool rx_q_compl_vmid_en;
/* Rx completion VMID */
unsigned int rx_q_compl_vmid;
};
/**
* Header split, buffer 2 per queue configuration
* When header split is enabled, Buffer_2 is used as an address for the header
* data. Buffer_2 is defined as 32-bits in the RX descriptor and it is defined
* that the MSB ([63:32]) of Buffer_1 is used as address [63:32] for the header
* address.
*/
struct al_udma_gen_hdr_split_buff2_q_conf {
/*
* MSB of the 64-bit address (bits [63:32]) that can be used for header
* split for this queue
*/
unsigned int addr_msb;
/*
* Determine how to select the MSB (bits [63:32]) of the address when
* header split is enabled (4 bits, one per byte)
* - Bits [3:0]:
* [0] selector for bits [39:32]
* [1] selector for bits [47:40]
* [2] selector for bits [55:48]
* [3] selector for bits [63:55]
* - Bit value:
* 0 Use Buffer_1 (legacy operation)
* 1 Use the queue configuration 'addr_msb'
*/
unsigned int add_msb_sel;
};
/* Report Error - to be used for abort */
void al_udma_err_report(struct al_udma *udma);
/* Statistics - TBD */
void al_udma_stats_get(struct al_udma *udma);
/* Misc configurations */
/* Configure AXI configuration */
int al_udma_axi_set(struct udma_gen_axi *axi_regs,
struct al_udma_axi_conf *axi);
/* Configure UDMA AXI M2S configuration */
int al_udma_m2s_axi_set(struct al_udma *udma,
struct al_udma_m2s_axi_conf *axi_m2s);
/* Configure UDMA AXI S2M configuration */
int al_udma_s2m_axi_set(struct al_udma *udma,
struct al_udma_s2m_axi_conf *axi_s2m);
/* Configure M2S packet len */
int al_udma_m2s_packet_size_cfg_set(struct al_udma *udma,
struct al_udma_m2s_pkt_len_conf *conf);
/* Configure M2S UDMA descriptor prefetch */
int al_udma_m2s_pref_set(struct al_udma *udma,
struct al_udma_m2s_desc_pref_conf *conf);
int al_udma_m2s_pref_get(struct al_udma *udma,
struct al_udma_m2s_desc_pref_conf *conf);
/* set m2s packet's max descriptors (including meta descriptors) */
#define AL_UDMA_M2S_MAX_ALLOWED_DESCS_PER_PACKET 31
int al_udma_m2s_max_descs_set(struct al_udma *udma, uint8_t max_descs);
/* set s2m packets' max descriptors */
#define AL_UDMA_S2M_MAX_ALLOWED_DESCS_PER_PACKET 31
int al_udma_s2m_max_descs_set(struct al_udma *udma, uint8_t max_descs);
/* Configure S2M UDMA descriptor prefetch */
int al_udma_s2m_pref_set(struct al_udma *udma,
struct al_udma_s2m_desc_pref_conf *conf);
int al_udma_m2s_pref_get(struct al_udma *udma,
struct al_udma_m2s_desc_pref_conf *conf);
/* Configure S2M UDMA data write */
int al_udma_s2m_data_write_set(struct al_udma *udma,
struct al_udma_s2m_data_write_conf *conf);
/* Configure the s2m full line write feature */
int al_udma_s2m_full_line_write_set(struct al_udma *umda, al_bool enable);
/* Configure S2M UDMA completion */
int al_udma_s2m_completion_set(struct al_udma *udma,
struct al_udma_s2m_completion_conf *conf);
/* Configure the M2S UDMA scheduling mode */
int al_udma_m2s_sc_set(struct al_udma *udma,
struct al_udma_m2s_dwrr_conf *sched);
/* Configure the M2S UDMA rate limitation */
int al_udma_m2s_rlimit_set(struct al_udma *udma,
struct al_udma_m2s_rlimit_mode *mode);
int al_udma_m2s_rlimit_reset(struct al_udma *udma);
/* Configure the M2S Stream rate limitation */
int al_udma_m2s_strm_rlimit_set(struct al_udma *udma,
struct al_udma_m2s_rlimit_cfg *conf);
int al_udma_m2s_strm_rlimit_act(struct al_udma *udma,
enum al_udma_m2s_rlimit_action act);
/* Configure the M2S UDMA Q rate limitation */
int al_udma_m2s_q_rlimit_set(struct al_udma_q *udma_q,
struct al_udma_m2s_rlimit_cfg *conf);
int al_udma_m2s_q_rlimit_act(struct al_udma_q *udma_q,
enum al_udma_m2s_rlimit_action act);
/* Configure the M2S UDMA Q scheduling mode */
int al_udma_m2s_q_sc_set(struct al_udma_q *udma_q,
struct al_udma_m2s_q_dwrr_conf *conf);
int al_udma_m2s_q_sc_pause(struct al_udma_q *udma_q, al_bool set);
int al_udma_m2s_q_sc_reset(struct al_udma_q *udma_q);
/* M2S UDMA completion and application timeouts */
int al_udma_m2s_comp_timeouts_set(struct al_udma *udma,
struct al_udma_m2s_comp_timeouts *conf);
int al_udma_m2s_comp_timeouts_get(struct al_udma *udma,
struct al_udma_m2s_comp_timeouts *conf);
/* UDMA get revision */
static INLINE unsigned int al_udma_get_revision(struct unit_regs __iomem *unit_regs)
{
return (al_reg_read32(&unit_regs->gen.dma_misc.revision)
& UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_MASK) >>
UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_SHIFT;
}
/**
* S2M UDMA Configure the expected behavior of Rx/S2M UDMA when there are no Rx Descriptors.
*
* @param udma
* @param drop_packet when set to true, the UDMA will drop packet.
* @param gen_interrupt when set to true, the UDMA will generate
* no_desc_hint interrupt when a packet received and the UDMA
* doesn't find enough free descriptors for it.
* @param wait_for_desc_timeout timeout in SB cycles to wait for new
* descriptors before dropping the packets.
* Notes:
* - The hint interrupt is raised immediately without waiting
* for new descs.
* - value 0 means wait for ever.
*
* Notes:
* - When get_interrupt is set, the API won't program the iofic to unmask this
* interrupt, in this case the callee should take care for doing that unmask
* using the al_udma_iofic_config() API.
*
* - The hardware's default configuration is: no drop packet, generate hint
* interrupt.
* - This API must be called once and before enabling the UDMA
*
* @return 0 if no error found.
*/
int al_udma_s2m_no_desc_cfg_set(struct al_udma *udma, al_bool drop_packet, al_bool gen_interrupt, uint32_t wait_for_desc_timeout);
/**
* S2M UDMA configure a queue's completion update
*
* @param q_udma
* @param enable set to true to enable completion update
*
* completion update better be disabled for tx queues as those descriptors
* doesn't carry useful information, thus disabling it saves DMA accesses.
*
* @return 0 if no error found.
*/
int al_udma_s2m_q_compl_updade_config(struct al_udma_q *udma_q, al_bool enable);
/**
* S2M UDMA configure a queue's completion descriptors coalescing
*
* @param q_udma
* @param enable set to true to enable completion coalescing
* @param coal_timeout in South Bridge cycles.
*
* @return 0 if no error found.
*/
int al_udma_s2m_q_compl_coal_config(struct al_udma_q *udma_q, al_bool enable, uint32_t coal_timeout);
/**
* S2M UDMA configure completion descriptors write burst parameters
*
* @param udma
* @param burst_size completion descriptors write burst size in bytes.
*
* @return 0 if no error found.
*/int al_udma_s2m_compl_desc_burst_config(struct al_udma *udma, uint16_t
burst_size);
/**
* S2M UDMA configure a queue's completion header split
*
* @param q_udma
* @param enable set to true to enable completion header split
* @param force_hdr_split the header split length will be taken from the queue configuration
* @param hdr_len header split length.
*
* @return 0 if no error found.
*/
int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q,
al_bool enable,
al_bool force_hdr_split,
uint32_t hdr_len);
/* S2M UDMA per queue completion configuration */
int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q,
struct al_udma_s2m_q_comp_conf *conf);
/** UDMA VMID control configuration */
void al_udma_gen_vmid_conf_set(
struct unit_regs __iomem *unit_regs,
struct al_udma_gen_vmid_conf *conf);
/** UDMA VMID MSIX control configuration */
void al_udma_gen_vmid_msix_conf_set(
struct unit_regs __iomem *unit_regs,
struct al_udma_gen_vmid_msix_conf *conf);
/** UDMA VMID control advanced Tx queue configuration */
void al_udma_gen_vmid_advanced_tx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_tx_q_conf *conf);
/** UDMA VMID control advanced Rx queue configuration */
void al_udma_gen_vmid_advanced_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_vmid_advanced_rx_q_conf *conf);
/** UDMA header split buffer 2 Rx queue configuration */
void al_udma_gen_hdr_split_buff2_rx_q_conf(
struct al_udma_q *q,
struct al_udma_gen_hdr_split_buff2_q_conf *conf);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of UDMA config group */
#endif /* __AL_HAL_UDMA_CONFIG_H__ */

View File

@ -0,0 +1,497 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @file al_hal_udma_debug.c
*
* @brief Universal DMA HAL driver for debug
*
*/
#define DEBUG
#include <al_hal_common.h>
#include <al_hal_udma_regs.h>
#include <al_hal_udma_debug.h>
static void al_udma_regs_m2s_axi_print(struct al_udma *udma)
{
al_dbg("M2S AXI regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, comp_wr_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, comp_wr_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, data_rd_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_rd_cfg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, desc_wr_cfg_1);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, axi_m2s,
desc_wr_cfg_1,
max_axi_beats,
UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, axi_m2s,
desc_wr_cfg_1,
min_axi_beats,
UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, axi_m2s, ostand_cfg);
}
static void al_udma_regs_m2s_general_print(struct al_udma *udma)
{
al_dbg("M2S general regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, state);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state,
comp_ctrl,
UDMA_M2S_STATE_COMP_CTRL);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state,
stream_if,
UDMA_M2S_STATE_STREAM_IF);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state,
rd_ctrl,
UDMA_M2S_STATE_DATA_RD_CTRL);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s, state,
desc_pref,
UDMA_M2S_STATE_DESC_PREF);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, err_log_mask);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_0);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, log_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, data_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, header_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, unack_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, check_en);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, fifo_en);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, cfg_len);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, stream_cfg);
}
static void al_udma_regs_m2s_rd_print(struct al_udma *udma)
{
al_dbg("M2S read regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, desc_pref_cfg_3);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd,
desc_pref_cfg_3,
min_burst_below_thr,
UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd,
desc_pref_cfg_3,
min_burst_above_thr,
UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_rd,
desc_pref_cfg_3,
pref_thr,
UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rd, data_cfg);
}
static void al_udma_regs_m2s_dwrr_print(struct al_udma *udma)
{
al_dbg("M2S DWRR regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_dwrr, cfg_sched);
}
static void al_udma_regs_m2s_rate_limiter_print(struct al_udma *udma)
{
al_dbg("M2S rate limiter regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_rate_limiter, gen_cfg);
}
static void al_udma_regs_m2s_stream_rate_limiter_print(struct al_udma *udma)
{
al_dbg("M2S stream rate limiter regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter,
rlimit.cfg_1s);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter,
rlimit.cfg_cycle);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter,
rlimit.cfg_token_size_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter,
rlimit.cfg_token_size_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stream_rate_limiter,
rlimit.mask);
}
static void al_udma_regs_m2s_comp_print(struct al_udma *udma)
{
al_dbg("M2S completion regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_1c);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c,
comp_fifo_depth,
UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c,
unack_fifo_depth,
UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH);
AL_UDMA_PRINT_REG_BIT(udma, " ", "\n", m2s, m2s_comp, cfg_1c,
q_promotion,
UDMA_M2S_COMP_CFG_1C_Q_PROMOTION);
AL_UDMA_PRINT_REG_BIT(udma, " ", "\n", m2s, m2s_comp, cfg_1c,
force_rr,
UDMA_M2S_COMP_CFG_1C_FORCE_RR);
AL_UDMA_PRINT_REG_FIELD(udma, " ", "\n", "%d", m2s, m2s_comp, cfg_1c,
q_free_min,
UDMA_M2S_COMP_CFG_1C_Q_FREE_MIN);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_coal);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_comp, cfg_application_ack);
}
static void al_udma_regs_m2s_stat_print(struct al_udma *udma)
{
al_dbg("M2S statistics regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, cfg_st);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_pkt);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_bytes_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, tx_bytes_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, prefed_desc);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, comp_pkt);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, comp_desc);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_stat, ack_pkts);
}
static void al_udma_regs_m2s_feature_print(struct al_udma *udma)
{
al_dbg("M2S feature regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_4);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_feature, reg_5);
}
static void al_udma_regs_m2s_q_print(struct al_udma *udma, uint32_t qid)
{
al_dbg("M2S Q[%d] status regs:\n", qid);
al_reg_write32(&udma->udma_regs->m2s.m2s.indirect_ctrl, qid);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_pref_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_comp_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_rate_limit_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s, sel_dwrr_status);
al_dbg("M2S Q[%d] regs:\n", qid);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], status);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrbp_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrbp_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrl);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrhp);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdrtp);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tdcp);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrbp_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrbp_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], tcrhp);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.cfg_1s);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.cfg_cycle);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid],
rlimit.cfg_token_size_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid],
rlimit.cfg_token_size_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], rlimit.mask);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], dwrr_cfg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], comp_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", m2s, m2s_q[qid], q_tx_pkt);
}
static void al_udma_regs_s2m_axi_print(struct al_udma *udma)
{
al_dbg("S2M AXI regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_4);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_5);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, comp_wr_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, comp_wr_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, data_wr_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_rd_cfg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, desc_wr_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, ostand_cfg_rd);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, axi_s2m, ostand_cfg_wr);
}
static void al_udma_regs_s2m_general_print(struct al_udma *udma)
{
al_dbg("S2M general regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, state);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, err_log_mask);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_0);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, log_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, s_data_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, s_header_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, axi_data_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, unack_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, check_en);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, fifo_en);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, stream_cfg);
}
static void al_udma_regs_s2m_rd_print(struct al_udma *udma)
{
al_dbg("S2M read regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_rd, desc_pref_cfg_4);
}
static void al_udma_regs_s2m_wr_print(struct al_udma *udma)
{
al_dbg("S2M write regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_wr, data_cfg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_wr, data_cfg_1);
}
static void al_udma_regs_s2m_comp_print(struct al_udma *udma)
{
al_dbg("S2M completion regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_1c);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_2c);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_comp, cfg_application_ack);
}
static void al_udma_regs_s2m_stat_print(struct al_udma *udma)
{
al_dbg("S2M statistics regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, drop_pkt);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, rx_bytes_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, rx_bytes_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, prefed_desc);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, comp_pkt);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, comp_desc);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_stat, ack_pkts);
}
static void al_udma_regs_s2m_feature_print(struct al_udma *udma)
{
al_dbg("S2M feature regs:\n");
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_1);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_3);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_4);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_5);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_feature, reg_6);
}
static void al_udma_regs_s2m_q_print(struct al_udma *udma, uint32_t qid)
{
al_dbg("S2M Q[%d] status regs:\n", qid);
al_reg_write32(&udma->udma_regs->m2s.m2s.indirect_ctrl, qid);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, sel_pref_fifo_status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m, sel_comp_fifo_status);
al_dbg("S2M Q[%d] regs:\n", qid);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], status);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrbp_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrbp_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrl);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrhp);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdrtp);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rdcp);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrbp_low);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrbp_high);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrhp);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], rcrhp_internal);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], comp_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], comp_cfg_2);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], pkt_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], qos_cfg);
AL_UDMA_PRINT_REG(udma, " ", "\n", s2m, s2m_q[qid], q_rx_pkt);
}
void al_udma_regs_print(struct al_udma *udma, unsigned int mask)
{
uint32_t i;
if (!udma)
return;
if (udma->type == UDMA_TX) {
if (mask & AL_UDMA_DEBUG_AXI)
al_udma_regs_m2s_axi_print(udma);
if (mask & AL_UDMA_DEBUG_GENERAL)
al_udma_regs_m2s_general_print(udma);
if (mask & AL_UDMA_DEBUG_READ)
al_udma_regs_m2s_rd_print(udma);
if (mask & AL_UDMA_DEBUG_DWRR)
al_udma_regs_m2s_dwrr_print(udma);
if (mask & AL_UDMA_DEBUG_RATE_LIMITER)
al_udma_regs_m2s_rate_limiter_print(udma);
if (mask & AL_UDMA_DEBUG_STREAM_RATE_LIMITER)
al_udma_regs_m2s_stream_rate_limiter_print(udma);
if (mask & AL_UDMA_DEBUG_COMP)
al_udma_regs_m2s_comp_print(udma);
if (mask & AL_UDMA_DEBUG_STAT)
al_udma_regs_m2s_stat_print(udma);
if (mask & AL_UDMA_DEBUG_FEATURE)
al_udma_regs_m2s_feature_print(udma);
for (i = 0; i < DMA_MAX_Q; i++) {
if (mask & AL_UDMA_DEBUG_QUEUE(i))
al_udma_regs_m2s_q_print(udma, i);
}
} else {
if (mask & AL_UDMA_DEBUG_AXI)
al_udma_regs_s2m_axi_print(udma);
if (mask & AL_UDMA_DEBUG_GENERAL)
al_udma_regs_s2m_general_print(udma);
if (mask & AL_UDMA_DEBUG_READ)
al_udma_regs_s2m_rd_print(udma);
if (mask & AL_UDMA_DEBUG_WRITE)
al_udma_regs_s2m_wr_print(udma);
if (mask & AL_UDMA_DEBUG_COMP)
al_udma_regs_s2m_comp_print(udma);
if (mask & AL_UDMA_DEBUG_STAT)
al_udma_regs_s2m_stat_print(udma);
if (mask & AL_UDMA_DEBUG_FEATURE)
al_udma_regs_s2m_feature_print(udma);
for (i = 0; i < DMA_MAX_Q; i++) {
if (mask & AL_UDMA_DEBUG_QUEUE(i))
al_udma_regs_s2m_q_print(udma, i);
}
}
}
void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid)
{
struct al_udma_q *queue;
if (!udma)
return;
if (qid >= DMA_MAX_Q)
return;
queue = &udma->udma_q[qid];
al_dbg("Q[%d] struct:\n", qid);
al_dbg(" size_mask = 0x%08x\n", (uint32_t)queue->size_mask);
al_dbg(" q_regs = %p\n", queue->q_regs);
al_dbg(" desc_base_ptr = %p\n", queue->desc_base_ptr);
al_dbg(" next_desc_idx = %d\n", (uint16_t)queue->next_desc_idx);
al_dbg(" desc_ring_id = %d\n", (uint32_t)queue->desc_ring_id);
al_dbg(" cdesc_base_ptr = %p\n", queue->cdesc_base_ptr);
al_dbg(" cdesc_size = %d\n", (uint32_t)queue->cdesc_size);
al_dbg(" next_cdesc_idx = %d\n", (uint16_t)queue->next_cdesc_idx);
al_dbg(" end_cdesc_ptr = %p\n", queue->end_cdesc_ptr);
al_dbg(" comp_head_idx = %d\n", (uint16_t)queue->comp_head_idx);
al_dbg(" comp_head_ptr = %p\n", queue->comp_head_ptr);
al_dbg(" pkt_crnt_descs = %d\n", (uint32_t)queue->pkt_crnt_descs);
al_dbg(" comp_ring_id = %d\n", (uint32_t)queue->comp_ring_id);
al_dbg(" desc_phy_base = 0x%016llx\n", (uint64_t)queue->desc_phy_base);
al_dbg(" cdesc_phy_base = 0x%016llx\n",
(uint64_t)queue->cdesc_phy_base);
al_dbg(" flags = 0x%08x\n", (uint32_t)queue->flags);
al_dbg(" size = %d\n", (uint32_t)queue->size);
al_dbg(" status = %d\n", (uint32_t)queue->status);
al_dbg(" udma = %p\n", queue->udma);
al_dbg(" qid = %d\n", (uint32_t)queue->qid);
}
void al_udma_ring_print(struct al_udma *udma, uint32_t qid,
enum al_udma_ring_type rtype)
{
struct al_udma_q *queue;
uint32_t desc_size;
void *base_ptr;
uint32_t i;
if (!udma)
return;
if (qid >= DMA_MAX_Q)
return;
queue = &udma->udma_q[qid];
if (rtype == AL_RING_SUBMISSION) {
base_ptr = queue->desc_base_ptr;
desc_size = sizeof(union al_udma_desc);
if (base_ptr)
al_dbg("Q[%d] submission ring pointers:\n", qid);
else {
al_dbg("Q[%d] submission ring is not allocated\n", qid);
return;
}
} else {
base_ptr = queue->cdesc_base_ptr;
desc_size = queue->cdesc_size;
if (base_ptr)
al_dbg("Q[%d] completion ring pointers:\n", qid);
else {
al_dbg("Q[%d] completion ring is not allocated\n", qid);
return;
}
}
for (i = 0; i < queue->size; i++) {
uint32_t *curr_addr = (void*)((uint32_t)base_ptr + i * desc_size);
if (desc_size == 16)
al_dbg("[%04d](%p): %08x %08x %08x %08x\n",
i,
curr_addr,
(uint32_t)*curr_addr,
(uint32_t)*(curr_addr+1),
(uint32_t)*(curr_addr+2),
(uint32_t)*(curr_addr+3));
else if (desc_size == 8)
al_dbg("[%04d](%p): %08x %08x\n",
i,
curr_addr,
(uint32_t)*curr_addr,
(uint32_t)*(curr_addr+1));
else if (desc_size == 4)
al_dbg("[%04d](%p): %08x\n",
i,
curr_addr,
(uint32_t)*curr_addr);
else
break;
}
}

View File

@ -0,0 +1,134 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_udma_debug UDMA Debug
* @ingroup group_udma_api
* UDMA Debug
* @{
* @file al_hal_udma_debug.h
*
* @brief C Header file for the Universal DMA HAL driver for debug APIs
*
*/
#ifndef __AL_HAL_UDMA_DEBUG_H__
#define __AL_HAL_UDMA_DEBUG_H__
#include <al_hal_udma.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* UDMA register print helper macros */
#define AL_UDMA_PRINT_REG(UDMA, PREFIX, POSTFIX, TYPE, GROUP, REG) \
al_dbg(PREFIX #REG " = 0x%08x" POSTFIX, al_reg_read32( \
&(UDMA->udma_regs->TYPE.GROUP.REG)))
#define AL_UDMA_PRINT_REG_FIELD( \
UDMA, PREFIX, POSTFIX, FMT, TYPE, GROUP, REG, LBL, FIELD) \
al_dbg(PREFIX #LBL " = " FMT POSTFIX, al_reg_read32( \
&(UDMA->udma_regs->TYPE.GROUP.REG)) \
& FIELD ## _MASK >> FIELD ## _SHIFT)
#define AL_UDMA_PRINT_REG_BIT( \
UDMA, PREFIX, POSTFIX, TYPE, GROUP, REG, LBL, FIELD) \
al_dbg(PREFIX #LBL " = %d" POSTFIX, ((al_reg_read32( \
&(UDMA->udma_regs->TYPE.GROUP.REG)) \
& FIELD) != 0))
/* UDMA register print mask definitions */
#define AL_UDMA_DEBUG_QUEUE(n) AL_BIT(n)
#define AL_UDMA_DEBUG_AXI AL_BIT(DMA_MAX_Q)
#define AL_UDMA_DEBUG_GENERAL AL_BIT(DMA_MAX_Q + 1)
#define AL_UDMA_DEBUG_READ AL_BIT(DMA_MAX_Q + 2)
#define AL_UDMA_DEBUG_WRITE AL_BIT(DMA_MAX_Q + 3)
#define AL_UDMA_DEBUG_DWRR AL_BIT(DMA_MAX_Q + 4)
#define AL_UDMA_DEBUG_RATE_LIMITER AL_BIT(DMA_MAX_Q + 5)
#define AL_UDMA_DEBUG_STREAM_RATE_LIMITER AL_BIT(DMA_MAX_Q + 6)
#define AL_UDMA_DEBUG_COMP AL_BIT(DMA_MAX_Q + 7)
#define AL_UDMA_DEBUG_STAT AL_BIT(DMA_MAX_Q + 8)
#define AL_UDMA_DEBUG_FEATURE AL_BIT(DMA_MAX_Q + 9)
#define AL_UDMA_DEBUG_ALL 0xFFFFFFFF
/* Debug functions */
/**
* Print udma registers according to the provided mask
*
* @param udma udma data structure
* @param mask mask that specifies which registers groups to print
* e.g. AL_UDMA_DEBUG_AXI prints AXI registers, AL_UDMA_DEBUG_ALL prints all
* registers
*/
void al_udma_regs_print(struct al_udma *udma, unsigned int mask);
/**
* Print udma queue software structure
*
* @param udma udma data structure
* @param qid queue index
*/
void al_udma_q_struct_print(struct al_udma *udma, uint32_t qid);
/** UDMA ring type */
enum al_udma_ring_type {
AL_RING_SUBMISSION,
AL_RING_COMPLETION
};
/**
* Print the ring entries for the specified queue index and ring type
* (submission/completion)
*
* @param udma udma data structure
* @param qid queue index
* @param rtype udma ring type
*/
void al_udma_ring_print(struct al_udma *udma, uint32_t qid,
enum al_udma_ring_type rtype);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_HAL_UDMA_DEBUG_H__ */
/** @} end of UDMA debug group */

View File

@ -0,0 +1,151 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_udma_iofic.c
*
* @brief unit interrupts configurations
*
*/
#include "al_hal_udma_iofic.h"
#include "al_hal_udma_regs.h"
/*
* configure the interrupt registers, interrupts will are kept masked
*/
static int al_udma_main_iofic_config(struct al_iofic_regs __iomem *base,
enum al_iofic_mode mode)
{
switch (mode) {
case AL_IOFIC_MODE_LEGACY:
al_iofic_config(base, AL_INT_GROUP_A,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_MASK_MSI_X |
INT_CONTROL_GRP_CLEAR_ON_READ);
al_iofic_config(base, AL_INT_GROUP_B,
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
al_iofic_config(base, AL_INT_GROUP_C,
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
al_iofic_config(base, AL_INT_GROUP_D,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_MASK_MSI_X |
INT_CONTROL_GRP_CLEAR_ON_READ);
break;
case AL_IOFIC_MODE_MSIX_PER_Q:
al_iofic_config(base, AL_INT_GROUP_A,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_AUTO_MASK |
INT_CONTROL_GRP_AUTO_CLEAR);
al_iofic_config(base, AL_INT_GROUP_B,
INT_CONTROL_GRP_AUTO_CLEAR |
INT_CONTROL_GRP_AUTO_MASK |
INT_CONTROL_GRP_CLEAR_ON_READ);
al_iofic_config(base, AL_INT_GROUP_C,
INT_CONTROL_GRP_AUTO_CLEAR |
INT_CONTROL_GRP_AUTO_MASK |
INT_CONTROL_GRP_CLEAR_ON_READ);
al_iofic_config(base, AL_INT_GROUP_D,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
break;
case AL_IOFIC_MODE_MSIX_PER_GROUP:
al_iofic_config(base, AL_INT_GROUP_A,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_AUTO_CLEAR |
INT_CONTROL_GRP_AUTO_MASK);
al_iofic_config(base, AL_INT_GROUP_B,
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
al_iofic_config(base, AL_INT_GROUP_C,
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
al_iofic_config(base, AL_INT_GROUP_D,
INT_CONTROL_GRP_SET_ON_POSEDGE |
INT_CONTROL_GRP_CLEAR_ON_READ |
INT_CONTROL_GRP_MASK_MSI_X);
break;
default:
al_err("%s: invalid mode (%d)\n", __func__, mode);
return -EINVAL;
}
al_dbg("%s: base.%p mode %d\n", __func__, base, mode);
return 0;
}
/*
* configure the UDMA interrupt registers, interrupts are kept masked
*/
int al_udma_iofic_config(struct unit_regs __iomem *regs, enum al_iofic_mode mode,
uint32_t m2s_errors_disable,
uint32_t m2s_aborts_disable,
uint32_t s2m_errors_disable,
uint32_t s2m_aborts_disable)
{
int rc;
rc = al_udma_main_iofic_config(&regs->gen.interrupt_regs.main_iofic, mode);
if (rc != 0)
return rc;
al_iofic_unmask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, ~m2s_errors_disable);
al_iofic_abort_mask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, m2s_aborts_disable);
al_iofic_unmask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, ~s2m_errors_disable);
al_iofic_abort_mask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, s2m_aborts_disable);
al_dbg("%s base.%p mode %d\n", __func__, regs, mode);
return 0;
}
/*
* return the offset of the unmask register for a given group
*/
uint32_t __iomem * al_udma_iofic_unmask_offset_get(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group)
{
al_assert(al_udma_iofic_level_and_group_valid(level, group));
return al_iofic_unmask_offset_get(al_udma_iofic_reg_base_get(regs, level), group);
}
/** @} end of UDMA group */

View File

@ -0,0 +1,614 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_udma_interrupts UDMA I/O Fabric Interrupt Controller
* @ingroup group_udma_api
* UDMA IOFIC API
* @{
* @file al_hal_udma_iofic.h
*
* @brief C Header file for programming the interrupt controller that found
* in UDMA based units. These APIs rely and use some the Interrupt controller
* API under al_hal_iofic.h
*/
#ifndef __AL_HAL_UDMA_IOFIC_H__
#define __AL_HAL_UDMA_IOFIC_H__
#include <al_hal_common.h>
#include <al_hal_iofic.h>
#include <al_hal_udma_regs.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* Interrupt Mode
* This is the interrupt mode for the primary interrupt level The secondary
* interrupt level does not have mode and it is always a level sensitive
* interrupt that is reflected in group D of the primary.
*/
enum al_iofic_mode {
AL_IOFIC_MODE_LEGACY, /**< level-sensitive interrupt wire */
AL_IOFIC_MODE_MSIX_PER_Q, /**< per UDMA queue MSI-X interrupt */
AL_IOFIC_MODE_MSIX_PER_GROUP
};
/** interrupt controller level (primary/secondary) */
enum al_udma_iofic_level {
AL_UDMA_IOFIC_LEVEL_PRIMARY,
AL_UDMA_IOFIC_LEVEL_SECONDARY
};
/*
* The next four groups represents the standard 4 groups in the primary
* interrupt controller of each bus-master unit in the I/O Fabric.
* The first two groups can be used when accessing the secondary interrupt
* controller as well.
*/
#define AL_INT_GROUP_A 0 /**< summary of the below events */
#define AL_INT_GROUP_B 1 /**< RX completion queues */
#define AL_INT_GROUP_C 2 /**< TX completion queues */
#define AL_INT_GROUP_D 3 /**< Misc */
/*******************************************************************************
* Primary interrupt controller, group A bits
******************************************************************************/
/* Group A bits which are just summary bits of GROUP B, C and D */
#define AL_INT_GROUP_A_GROUP_B_SUM AL_BIT(0)
#define AL_INT_GROUP_A_GROUP_C_SUM AL_BIT(1)
#define AL_INT_GROUP_A_GROUP_D_SUM AL_BIT(2)
/*******************************************************************************
* MSIX entry indices
******************************************************************************/
/** MSIX entry index for summary of group D in group A */
#define AL_INT_MSIX_GROUP_A_SUM_D_IDX 2
/** MSIX entry index for RX completion queue 0 */
#define AL_INT_MSIX_RX_COMPLETION_START 3
/*******************************************************************************
* Primary interrupt controller, group D bits
******************************************************************************/
#define AL_INT_GROUP_D_CROSS_MAIL_BOXES \
(AL_BIT(0) | AL_BIT(1) | AL_BIT(2) | AL_BIT(3))
/** Summary of secondary interrupt controller, group A) */
#define AL_INT_GROUP_D_M2S AL_BIT(8)
/** Summary of secondary interrupt controller, group B) */
#define AL_INT_GROUP_D_S2M AL_BIT(9)
#define AL_INT_GROUP_D_SW_TIMER_INT AL_BIT(10)
#define AL_INT_GROUP_D_APP_EXT_INT AL_BIT(11)
#define AL_INT_GROUP_D_ALL \
AL_INT_GROUP_D_CROSS_MAIL_BOXES | \
AL_INT_GROUP_D_M2S | \
AL_INT_GROUP_D_S2M | \
AL_INT_GROUP_D_SW_TIMER_INT | \
AL_INT_GROUP_D_APP_EXT_INT
/*
* Until this point, all description above is for Groups A/B/C/D in the PRIMARY
* Interrupt controller.
* Following are definitions related to the secondary interrupt controller with
* two cause registers (group A and group B) that covers UDMA M2S/S2M errors.
* Secondary interrupt controller summary bits are not mapped to the Processor
* GIC directly, rather they are represented in Group D of the primary interrupt
* controller.
*/
/******************************************************************************
* Secondary interrupt Controller, Group A, which holds the TX (M2S) error
* interrupt bits
******************************************************************************/
/**
* MSIx response
* MSIX Bus generator response error, the Bus response received with error indication
*/
#define AL_INT_2ND_GROUP_A_M2S_MSIX_RESP AL_BIT(27)
/**
* MSIx timeout MSIX Bus generator timeout error.
* The generator didn't receive bus response for the MSIx write transaction.
*/
#define AL_INT_2ND_GROUP_A_M2S_MSIX_TO AL_BIT(26)
/** Prefetch header buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_HDR_PARITY AL_BIT(25)
/** Prefetch descriptor buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_DESC_PARITY AL_BIT(24)
/** Data buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_DATA_PARITY AL_BIT(23)
/** Data header buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_HDR_PARITY AL_BIT(22)
/** Completion coalescing buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_COMPL_COAL_PARITY AL_BIT(21)
/** UNACK packets buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_UNACK_PKT_PARITY AL_BIT(20)
/** ACK packets buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_ACK_PKT_PARITY AL_BIT(19)
/** AXI data buffer parity error */
#define AL_INT_2ND_GROUP_A_M2S_AX_DATA_PARITY AL_BIT(18)
/**
* Prefetch Ring ID error
* A wrong RingId was received while prefetching submission descriptor. This
* could indicate a software bug or hardware failure, unless the UDMA is
* working in a mode to ignore RingId (the al_udma_iofic_config() API can be
* used to configure the UDMA to ignore the Ring ID check)
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_RING_ID AL_BIT(17)
/**
* Prefetch last
* Error in last bit indication of the descriptor
* Descriptor with Last bit asserted is read from the queue to the prefetch
* FIFO when the prefetch engine is not in a middle of packet processing (a
* descriptor with First bit asserted should be read first to indicate start of
* packet)
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_LAST AL_BIT(16)
/**
* Prefetch first
* Error in first bit indication of the descriptor
* Descriptor with First bit asserted is read from the queue to the prefetch
* FIFO while the prefetch engine is in a middle of packet processing ( a
* descriptor with Last bit asserted should be read to indicate end of packet
* before starting a new one)
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_FIRST AL_BIT(15)
/**
* Prefetch max descriptors
* Number of descriptors per packet exceeds the configurable maximum
* descriptors per packet. This could indicate a software bug or a hardware
* failure. (The al_udma_m2s_max_descs_set() API is used to configure the
* maximum descriptors per packet)
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_MAX_DESC AL_BIT(14)
/**
* Packet length
* Packet length exceeds the configurable maximum packet size. The
* al_udma_m2s_packet_size_cfg_set() API is used to configure the maximum
* packet size)
*/
#define AL_INT_2ND_GROUP_A_M2S_PKT_LEN AL_BIT(13)
/**
* Prefetch AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_TO AL_BIT(12)
/**
* Prefetch AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_RESP AL_BIT(11)
/**
* Prefetch AXI parity
* Bus parity error on descriptor being prefetched
*/
#define AL_INT_2ND_GROUP_A_M2S_PREFETCH_AXI_PARITY AL_BIT(10)
/**
* Data AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_TO AL_BIT(9)
/**
* Data AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_RESP AL_BIT(8)
/**
* Data AXI parity
* Bus parity error on data being read
*/
#define AL_INT_2ND_GROUP_A_M2S_DATA_AXI_PARITY AL_BIT(7)
/**
* Completion AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_A_M2S_CONPL_AXI_TO AL_BIT(6)
/**
* Completion AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_A_M2S_COMPL_AXI_RESP AL_BIT(5)
/**
* Completion AXI parity
* Bus generator internal SRAM parity error
*/
#define AL_INT_2ND_GROUP_A_M2S_COMP_AXI_PARITY AL_BIT(4)
/**
* Stream timeout
* Application stream interface timeout indicating a failure at the Application
* layer (RAID, Ethernet etc)
*/
#define AL_INT_2ND_GROUP_A_M2S_STRM_TO AL_BIT(3)
/**
* Stream response
* Application stream interface response error indicating a failure at the
* Application layer (RAID, Ethernet etc)
*/
#define AL_INT_2ND_GROUP_A_M2S_STRM_RESP AL_BIT(2)
/**
* Stream parity
* Application stream interface parity error indicating a failure at the
* Application layer (RAID, Ethernet etc)
*/
#define AL_INT_2ND_GROUP_A_M2S_STRM_PARITY AL_BIT(1)
/**
* Stream completion mismatch
* Application stream interface, packet serial mismatch error indicating a
* failure at the Application layer (RAID, Ethernet etc)
*/
#define AL_INT_2ND_GROUP_A_M2S_STRM_COMPL_MISMATCH AL_BIT(0)
/*******************************************************************************
* Secondary interrupt Controller, Group B, which holds the RX (S2M) error
* interrupt bits
******************************************************************************/
/** Prefetch descriptor buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_DESC_PARITY AL_BIT(30)
/** Completion coalescing buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_COMPL_COAL_PARITY AL_BIT(29)
/** PRE-UNACK packets buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_PRE_UNACK_PKT_PARITY AL_BIT(28)
/** UNACK packets buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_UNACK_PKT_PARITY AL_BIT(27)
/** Data buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_DATA_PARITY AL_BIT(26)
/** Data header buffer parity error */
#define AL_INT_2ND_GROUP_B_S2M_DATA_HDR_PARITY AL_BIT(25)
/**
* Packet length
* Application stream interface, Data counter length mismatch with metadata
* packet length indicating a failure at the Application layer (RAID, Ethernet
* etc)
*/
#define AL_INT_2ND_GROUP_B_S2M_PKT_LEN AL_BIT(24)
/**
* Stream last
* Application stream interface, error in Last bit indication, this error is
* asserted when a 'last' indication is asserted on the stream interface
* (between the application and the UDMA) when the interface is not in the
* middle of packet, meaning that there was no 'first' indication before. This
* indicates a failure at the application layer.
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_LAST AL_BIT(23)
/**
* Stream first
* Application stream interface error in first bit indication, this error is
* asserted when a 'first' indication is asserted on the stream interface
* (between the application and the UDMA) when the interface is in the middle
* of packet, meaning that there was a 'first' indication before and the UDMA
* is waiting for a 'last' indication to end the packet. This indicates a
* failure at the application layer.
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_FIRST AL_BIT(22)
/**
* Stream data
* Application stream interface, error indication during data transaction
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_DATA AL_BIT(21)
/**
* Stream Data parity
* Application stream interface, parity error during data transaction
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_DATA_PARITY AL_BIT(20)
/**
* Stream Header error
* Application stream interface, error indication during header transaction
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_HDR AL_BIT(19)
/**
* Stream Header parity
* Application stream interface, parity error during header transaction
*/
#define AL_INT_2ND_GROUP_B_S2M_STRM_HDR_PARITY AL_BIT(18)
/**
* Completion UNACK
* Completion write, UNACK timeout due to completion FIFO back pressure
*/
#define AL_INT_2ND_GROUP_B_S2M_COMPL_UNACK AL_BIT(17)
/**
* Completion stream
* Completion write, UNACK timeout due to stream ACK FIFO back pressure
*/
#define AL_INT_2ND_GROUP_B_S2M_COMPL_STRM AL_BIT(16)
/**
* Completion AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_TO AL_BIT(15)
/**
* Completion AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_RESP AL_BIT(14)
/**
* Completion AXI parity
* Completion Bus generator internal SRAM parity error
*/
#define AL_INT_2ND_GROUP_B_S2M_COMPL_AXI_PARITY AL_BIT(13)
/**
* Prefetch saturate
* Prefetch engine, packet length counter saturated (32 bit) , this is caused
* by an error at the application layer which sends packet data without
* 'last'/'first' indication.
*/
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_SAT AL_BIT(12)
/**
* Prefetch ring ID
* Prefetch engine, Ring ID is not matching the expected RingID. This could
* indicate a software bug or hardware failure, unless the UDMA is working in a
* mode to ignore RingId (the al_udma_iofic_config() API can be used to
* configure the UDMA to ignore the Ring ID check)
*/
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_RING_ID AL_BIT(11)
/**
* Prefetch AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_TO AL_BIT(10)
/**
* Prefetch AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_RESP AL_BIT(9)
/**
* Prefetch AXI parity
* Bus parity error on descriptor being prefetched
*/
#define AL_INT_2ND_GROUP_B_S2M_PREFETCH_AXI_PARITY AL_BIT(8)
/**
* No descriptors hint
* Data write, Hint to the SW that there are not enough descriptors in the
* queue for the current received packet. This is considered a hint and not an
* error, as it could be a normal situation in certain application. The S2M
* UDMA behavior when it runs out of Rx Descriptor is controlled by driver
* which can use this hint to add more descriptors to the Rx queue.
*/
#define AL_INT_2ND_GROUP_B_S2M_NO_DESC_HINT AL_BIT(7)
/**
* No descriptors timeout
* Data write, Timeout indication when there are not enough descriptors for the
* current packet and the timeout expires. The S2M UDMA behavior when it runs
* out of Rx Descriptor is controlled by driver which can use this hint to add
* more descriptors to the Rx queue. The al_udma_s2m_no_desc_cfg_set() is used
* to configure theUDMA S2M timeout and behavior when there are no Rx
* descriptors for the received packet.
*/
#define AL_INT_2ND_GROUP_B_S2M_NO_DESC_TO AL_BIT(6)
/**
* Promotion indication
* Data write, the data write engine checks the queue number of the two packets
* at the head of the data FIFO, the data write engine notify the prefetch
* engine to promote these queue numbers in the prefetch scheduler to make sure
* that these queue will have RX descriptors for these packets. This error
* indicates that the prefetch promotion didn't work for the second packet in
* the FIFO. This is an indication used for system debug and not an error.
*/
#define AL_INT_2ND_GROUP_B_S2M_PROM_IND AL_BIT(5)
/**
* Header split ignored
* Data write, The application requested header split but the buffer descriptor
* doesn't include a second buffer for the header
*/
#define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_IGNORED AL_BIT(4)
/**
* Header split length
* Data write, The application requested header split and the length of the
* second buffer allocated for the header is not enough for the requested
* header length. The remaining of the header is written to buffer 1 (data
* buffer).
*/
#define AL_INT_2ND_GROUP_B_S2M_HDR_SPLT_LEN AL_BIT(3)
/**
* Data AXI timeout
* Bus request to I/O Fabric timeout error
*/
#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_TO AL_BIT(2)
/**
* Data AXI response
* Bus response from I/O Fabric error
*/
#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_RESP AL_BIT(1)
/**
* Data AXI parity
* Bus parity error on data being read
*/
#define AL_INT_2ND_GROUP_B_S2M_DATA_AXI_PARITY AL_BIT(0)
/*******************************************************************************
* Configurations
******************************************************************************/
/**
* Configure the UDMA interrupt controller registers, interrupts will are kept
* masked.
* This is a static setting that should be called while initialized the
* interrupt controller within a given UDMA, and should not be modified during
* runtime unless the UDMA is completely disabled. The first argument sets the
* interrupt and MSIX modes. The m2s/s2m errors/abort are a set of bit-wise
* masks to define the behaviour of the UDMA once an error happens: The _abort
* will put the UDMA in abort state once an error happens The _error bitmask
* will indicate and error in the secondary cause register but will not abort.
* The bit-mask that the _errors_disable and _aborts_disable are described in
* 'AL_INT_2ND_GROUP_A_*' and 'AL_INT_2ND_GROUP_B_*'
*
* @param regs pointer to unit registers
* @param mode interrupt scheme mode (legacy, MSI-X..)
* @param m2s_errors_disable
* This is a bit-wise mask, to indicate which one of the error causes in
* secondary interrupt group_A should generate an interrupt. When a bit is
* set, the error cause is ignored.
* Recommended value: 0 (enable all errors).
* @param m2s_aborts_disable
* This is a bit-wise mask, to indicate which one of the error causes in
* secondary interrupt group_A should automatically put the UDMA in
* abort state. When a bit is set, the error cause does cause an abort.
* Recommended value: 0 (enable all aborts).
* @param s2m_errors_disable
* This is a bit-wise mask, to indicate which one of the error causes in
* secondary interrupt group_A should generate an interrupt. When a bit is
* set, the error cause is ignored.
* Recommended value: 0xE0 (disable hint errors).
* @param s2m_aborts_disable
* This is a bit-wise mask, to indicate which one of the error causes in
* secondary interrupt group_A should automatically put the UDMA in
* abort state. When a bit is set, the error cause does cause an abort.
* Recommended value: 0xE0 (disable hint aborts).
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_udma_iofic_config(struct unit_regs __iomem *regs,
enum al_iofic_mode mode,
uint32_t m2s_errors_disable,
uint32_t m2s_aborts_disable,
uint32_t s2m_errors_disable,
uint32_t s2m_aborts_disable);
/**
* return the offset of the unmask register for a given group.
* this function can be used when the upper layer wants to directly
* access the unmask regiter and bypass the al_udma_iofic_unmask() API.
*
* @param regs pointer to udma registers
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
* @return the offset of the unmask register.
*/
uint32_t __iomem * al_udma_iofic_unmask_offset_get(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group);
/**
* Get the interrupt controller base address for either the primary or secondary
* interrupt controller
*
* @param regs pointer to udma unit registers
* @param level the interrupt controller level (primary / secondary)
*
* @returns The interrupt controller base address
*
*/
static INLINE void __iomem *al_udma_iofic_reg_base_get(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level)
{
void __iomem *iofic_regs = (level == AL_UDMA_IOFIC_LEVEL_PRIMARY) ?
(void __iomem *)&regs->gen.interrupt_regs.main_iofic :
(void __iomem *)&regs->gen.interrupt_regs.secondary_iofic_ctrl;
return iofic_regs;
}
/**
* Check the interrupt controller level/group validity
*
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
*
* @returns 0 - invalid, 1 - valid
*
*/
static INLINE int al_udma_iofic_level_and_group_valid(
enum al_udma_iofic_level level,
int group)
{
if (((level == AL_UDMA_IOFIC_LEVEL_PRIMARY) && (group >= 0) && (group < 4)) ||
((level == AL_UDMA_IOFIC_LEVEL_SECONDARY) && (group >= 0) && (group < 2)))
return 1;
return 0;
}
/**
* unmask specific interrupts for a given group
* this functions uses the interrupt mask clear register to guarantee atomicity
* it's safe to call it while the mask is changed by the HW (auto mask) or another cpu.
*
* @param regs pointer to udma unit registers
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
* @param mask bitwise of interrupts to unmask, set bits will be unmasked.
*/
static INLINE void al_udma_iofic_unmask(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group,
uint32_t mask)
{
al_assert(al_udma_iofic_level_and_group_valid(level, group));
al_iofic_unmask(al_udma_iofic_reg_base_get(regs, level), group, mask);
}
/**
* mask specific interrupts for a given group
* this functions modifies interrupt mask register, the callee must make sure
* the mask is not changed by another cpu.
*
* @param regs pointer to udma unit registers
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
* @param mask bitwise of interrupts to mask, set bits will be masked.
*/
static INLINE void al_udma_iofic_mask(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group,
uint32_t mask)
{
al_assert(al_udma_iofic_level_and_group_valid(level, group));
al_iofic_mask(al_udma_iofic_reg_base_get(regs, level), group, mask);
}
/**
* read interrupt cause register for a given group
* this will clear the set bits if the Clear on Read mode enabled.
* @param regs pointer to udma unit registers
* @param level the interrupt controller level (primary / secondary)
* @param group the interrupt group ('AL_INT_GROUP_*')
*/
static INLINE uint32_t al_udma_iofic_read_cause(
struct unit_regs __iomem *regs,
enum al_udma_iofic_level level,
int group)
{
al_assert(al_udma_iofic_level_and_group_valid(level, group));
return al_iofic_read_cause(al_udma_iofic_reg_base_get(regs, level), group);
}
#endif
/** @} end of UDMA group */

View File

@ -0,0 +1,66 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_UDMA_IOFIC_REG_H
#define __AL_HAL_UDMA_IOFIC_REG_H
#include "al_hal_iofic_regs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** This structure covers all interrupt registers of a given UDMA, which is
* built of an al_iofic_regs, which is the common I/O Fabric Interrupt
* controller (IOFIC), and additional two interrupts groups dedicated for the
* application-specific engine attached to the UDMA, the interrupt summary
* of those two groups routed to gourp D of the main controller.
*/
struct udma_iofic_regs {
struct al_iofic_regs main_iofic;
uint32_t rsrvd1[(0x1c00) >> 2];
struct al_iofic_grp_ctrl secondary_iofic_ctrl[2];
};
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_UDMA_IOFIC_REG_H */

View File

@ -0,0 +1,618 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_udma_main.c
*
* @brief Universal DMA HAL driver for main functions (initialization, data path)
*
*/
#include <al_hal_udma.h>
#include <al_hal_udma_config.h>
#define AL_UDMA_Q_RST_TOUT 10000 /* Queue reset timeout [uSecs] */
#define UDMA_STATE_IDLE 0x0
#define UDMA_STATE_NORMAL 0x1
#define UDMA_STATE_ABORT 0x2
#define UDMA_STATE_RESERVED 0x3
const char *const al_udma_states_name[] = {
"Disable",
"Idle",
"Normal",
"Abort",
"Reset"
};
#define AL_UDMA_INITIAL_RING_ID 1
/* dma_q flags */
#define AL_UDMA_Q_FLAGS_IGNORE_RING_ID AL_BIT(0)
#define AL_UDMA_Q_FLAGS_NO_COMP_UPDATE AL_BIT(1)
#define AL_UDMA_Q_FLAGS_EN_COMP_COAL AL_BIT(2)
static void al_udma_set_defaults(struct al_udma *udma)
{
uint32_t tmp;
uint8_t rev_id = udma->rev_id;
if (udma->type == UDMA_TX) {
struct unit_regs* tmp_unit_regs =
(struct unit_regs*)udma->udma_regs;
/* Setting the data fifo depth to 4K (256 strips of 16B)
* This allows the UDMA to have 16 outstanding writes */
if (rev_id >= AL_UDMA_REV_ID_2) {
al_reg_write32_masked(&tmp_unit_regs->m2s.m2s_rd.data_cfg,
UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK,
256 << UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_SHIFT);
}
if (rev_id == AL_UDMA_REV_ID_0)
/* disable AXI timeout for M0*/
al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 0);
else
/* set AXI timeout to 1M (~2.6 ms) */
al_reg_write32(&tmp_unit_regs->gen.axi.cfg_1, 1000000);
al_reg_write32(&tmp_unit_regs->m2s.m2s_comp.cfg_application_ack
, 0); /* Ack time out */
if (rev_id == AL_UDMA_REV_ID_0) {
tmp = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
tmp &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
tmp |= 4 << UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT;
al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1
, tmp);
}
}
if (udma->type == UDMA_RX) {
al_reg_write32(
&udma->udma_regs->s2m.s2m_comp.cfg_application_ack, 0);
/* Ack time out */
}
}
/**
* misc queue configurations
*
* @param udma_q udma queue data structure
*
* @return 0
*/
static int al_udma_q_config(struct al_udma_q *udma_q)
{
uint32_t *reg_addr;
uint32_t val;
if (udma_q->udma->type == UDMA_TX) {
reg_addr = &udma_q->q_regs->m2s_q.rlimit.mask;
val = al_reg_read32(reg_addr);
// enable DMB
val &= ~UDMA_M2S_Q_RATE_LIMIT_MASK_INTERNAL_PAUSE_DMB;
al_reg_write32(reg_addr, val);
}
return 0;
}
/**
* set the queue's completion configuration register
*
* @param udma_q udma queue data structure
*
* @return 0
*/
static int al_udma_q_config_compl(struct al_udma_q *udma_q)
{
uint32_t *reg_addr;
uint32_t val;
if (udma_q->udma->type == UDMA_TX)
reg_addr = &udma_q->q_regs->m2s_q.comp_cfg;
else
reg_addr = &udma_q->q_regs->s2m_q.comp_cfg;
val = al_reg_read32(reg_addr);
if (udma_q->flags & AL_UDMA_Q_FLAGS_NO_COMP_UPDATE)
val &= ~UDMA_M2S_Q_COMP_CFG_EN_COMP_RING_UPDATE;
else
val |= UDMA_M2S_Q_COMP_CFG_EN_COMP_RING_UPDATE;
if (udma_q->flags & AL_UDMA_Q_FLAGS_EN_COMP_COAL)
val &= ~UDMA_M2S_Q_COMP_CFG_DIS_COMP_COAL;
else
val |= UDMA_M2S_Q_COMP_CFG_DIS_COMP_COAL;
al_reg_write32(reg_addr, val);
/* set the completion queue size */
if (udma_q->udma->type == UDMA_RX) {
val = al_reg_read32(
&udma_q->udma->udma_regs->s2m.s2m_comp.cfg_1c);
val &= ~UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
/* the register expects it to be in words */
val |= (udma_q->cdesc_size >> 2)
& UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
al_reg_write32(&udma_q->udma->udma_regs->s2m.s2m_comp.cfg_1c
, val);
}
return 0;
}
/**
* reset the queues pointers (Head, Tail, etc) and set the base addresses
*
* @param udma_q udma queue data structure
*/
static int al_udma_q_set_pointers(struct al_udma_q *udma_q)
{
/* reset the descriptors ring pointers */
/* assert descriptor base address aligned. */
al_assert((AL_ADDR_LOW(udma_q->desc_phy_base) &
~UDMA_M2S_Q_TDRBP_LOW_ADDR_MASK) == 0);
al_reg_write32(&udma_q->q_regs->rings.drbp_low,
AL_ADDR_LOW(udma_q->desc_phy_base));
al_reg_write32(&udma_q->q_regs->rings.drbp_high,
AL_ADDR_HIGH(udma_q->desc_phy_base));
al_reg_write32(&udma_q->q_regs->rings.drl, udma_q->size);
/* if completion ring update disabled */
if (udma_q->cdesc_base_ptr == NULL) {
udma_q->flags |= AL_UDMA_Q_FLAGS_NO_COMP_UPDATE;
} else {
/* reset the completion descriptors ring pointers */
/* assert completion base address aligned. */
al_assert((AL_ADDR_LOW(udma_q->cdesc_phy_base) &
~UDMA_M2S_Q_TCRBP_LOW_ADDR_MASK) == 0);
al_reg_write32(&udma_q->q_regs->rings.crbp_low,
AL_ADDR_LOW(udma_q->cdesc_phy_base));
al_reg_write32(&udma_q->q_regs->rings.crbp_high,
AL_ADDR_HIGH(udma_q->cdesc_phy_base));
}
al_udma_q_config_compl(udma_q);
return 0;
}
/**
* enable/disable udma queue
*
* @param udma_q udma queue data structure
* @param enable none zero value enables the queue, zero means disable
*
* @return 0
*/
static int al_udma_q_enable(struct al_udma_q *udma_q, int enable)
{
uint32_t reg = al_reg_read32(&udma_q->q_regs->rings.cfg);
if (enable) {
reg |= (UDMA_M2S_Q_CFG_EN_PREF | UDMA_M2S_Q_CFG_EN_SCHEDULING);
udma_q->status = AL_QUEUE_ENABLED;
} else {
reg &= ~(UDMA_M2S_Q_CFG_EN_PREF | UDMA_M2S_Q_CFG_EN_SCHEDULING);
udma_q->status = AL_QUEUE_DISABLED;
}
al_reg_write32(&udma_q->q_regs->rings.cfg, reg);
return 0;
}
/************************ API functions ***************************************/
/* Initializations functions */
/*
* Initialize the udma engine
*/
int al_udma_init(struct al_udma *udma, struct al_udma_params *udma_params)
{
int i;
al_assert(udma);
if (udma_params->num_of_queues > DMA_MAX_Q) {
al_err("udma: invalid num_of_queues parameter\n");
return -EINVAL;
}
udma->type = udma_params->type;
udma->num_of_queues = udma_params->num_of_queues;
udma->gen_regs = &udma_params->udma_regs_base->gen;
if (udma->type == UDMA_TX)
udma->udma_regs = (union udma_regs *)&udma_params->udma_regs_base->m2s;
else
udma->udma_regs = (union udma_regs *)&udma_params->udma_regs_base->s2m;
udma->rev_id = al_udma_get_revision(udma_params->udma_regs_base);
if (udma_params->name == NULL)
udma->name = "";
else
udma->name = udma_params->name;
udma->state = UDMA_DISABLE;
for (i = 0; i < DMA_MAX_Q; i++) {
udma->udma_q[i].status = AL_QUEUE_NOT_INITIALIZED;
}
/* initialize configuration registers to correct values */
al_udma_set_defaults(udma);
al_dbg("udma [%s] initialized. base %p\n", udma->name,
udma->udma_regs);
return 0;
}
/*
* Initialize the udma queue data structure
*/
int al_udma_q_init(struct al_udma *udma, uint32_t qid,
struct al_udma_q_params *q_params)
{
struct al_udma_q *udma_q;
al_assert(udma);
al_assert(q_params);
if (qid >= udma->num_of_queues) {
al_err("udma: invalid queue id (%d)\n", qid);
return -EINVAL;
}
if (udma->udma_q[qid].status == AL_QUEUE_ENABLED) {
al_err("udma: queue (%d) already enabled!\n", qid);
return -EIO;
}
if (q_params->size < AL_UDMA_MIN_Q_SIZE) {
al_err("udma: queue (%d) size too small\n", qid);
return -EINVAL;
}
if (q_params->size > AL_UDMA_MAX_Q_SIZE) {
al_err("udma: queue (%d) size too large\n", qid);
return -EINVAL;
}
if (q_params->size & (q_params->size - 1)) {
al_err("udma: queue (%d) size (%d) must be power of 2\n",
q_params->size, qid);
return -EINVAL;
}
udma_q = &udma->udma_q[qid];
/* set the queue's regs base address */
if (udma->type == UDMA_TX)
udma_q->q_regs = (union udma_q_regs __iomem *)
&udma->udma_regs->m2s.m2s_q[qid];
else
udma_q->q_regs = (union udma_q_regs __iomem *)
&udma->udma_regs->s2m.s2m_q[qid];
udma_q->adapter_rev_id = q_params->adapter_rev_id;
udma_q->size = q_params->size;
udma_q->size_mask = q_params->size - 1;
udma_q->desc_base_ptr = q_params->desc_base;
udma_q->desc_phy_base = q_params->desc_phy_base;
udma_q->cdesc_base_ptr = q_params->cdesc_base;
udma_q->cdesc_phy_base = q_params->cdesc_phy_base;
udma_q->cdesc_size = q_params->cdesc_size;
udma_q->next_desc_idx = 0;
udma_q->next_cdesc_idx = 0;
udma_q->end_cdesc_ptr = (uint8_t *) udma_q->cdesc_base_ptr +
(udma_q->size - 1) * udma_q->cdesc_size;
udma_q->comp_head_idx = 0;
udma_q->comp_head_ptr = (union al_udma_cdesc *)udma_q->cdesc_base_ptr;
udma_q->desc_ring_id = AL_UDMA_INITIAL_RING_ID;
udma_q->comp_ring_id = AL_UDMA_INITIAL_RING_ID;
#if 0
udma_q->desc_ctrl_bits = AL_UDMA_INITIAL_RING_ID <<
AL_M2S_DESC_RING_ID_SHIFT;
#endif
udma_q->pkt_crnt_descs = 0;
udma_q->flags = 0;
udma_q->status = AL_QUEUE_DISABLED;
udma_q->udma = udma;
udma_q->qid = qid;
/* start hardware configuration: */
al_udma_q_config(udma_q);
/* reset the queue pointers */
al_udma_q_set_pointers(udma_q);
/* enable the q */
al_udma_q_enable(udma_q, 1);
al_dbg("udma [%s %d]: %s q init. size 0x%x\n"
" desc ring info: phys base 0x%llx virt base %p\n"
" cdesc ring info: phys base 0x%llx virt base %p "
"entry size 0x%x",
udma_q->udma->name, udma_q->qid,
udma->type == UDMA_TX ? "Tx" : "Rx",
q_params->size,
(unsigned long long)q_params->desc_phy_base,
q_params->desc_base,
(unsigned long long)q_params->cdesc_phy_base,
q_params->cdesc_base,
q_params->cdesc_size);
return 0;
}
/*
* Reset a udma queue
*/
int al_udma_q_reset(struct al_udma_q *udma_q)
{
unsigned int remaining_time = AL_UDMA_Q_RST_TOUT;
uint32_t *status_reg;
uint32_t *dcp_reg;
uint32_t *crhp_reg;
uint32_t *q_sw_ctrl_reg;
al_assert(udma_q);
/* De-assert scheduling and prefetch */
al_udma_q_enable(udma_q, 0);
/* Wait for scheduling and prefetch to stop */
status_reg = &udma_q->q_regs->rings.status;
while (remaining_time) {
uint32_t status = al_reg_read32(status_reg);
if (!(status & (UDMA_M2S_Q_STATUS_PREFETCH |
UDMA_M2S_Q_STATUS_SCHEDULER)))
break;
remaining_time--;
al_udelay(1);
}
if (!remaining_time) {
al_err("udma [%s %d]: %s timeout waiting for prefetch and "
"scheduler disable\n", udma_q->udma->name, udma_q->qid,
__func__);
return -ETIMEDOUT;
}
/* Wait for the completion queue to reach to the same pointer as the
* prefetch stopped at ([TR]DCP == [TR]CRHP) */
dcp_reg = &udma_q->q_regs->rings.dcp;
crhp_reg = &udma_q->q_regs->rings.crhp;
while (remaining_time) {
uint32_t dcp = al_reg_read32(dcp_reg);
uint32_t crhp = al_reg_read32(crhp_reg);
if (dcp == crhp)
break;
remaining_time--;
al_udelay(1);
};
if (!remaining_time) {
al_err("udma [%s %d]: %s timeout waiting for dcp==crhp\n",
udma_q->udma->name, udma_q->qid, __func__);
return -ETIMEDOUT;
}
/* Assert the queue reset */
if (udma_q->udma->type == UDMA_TX)
q_sw_ctrl_reg = &udma_q->q_regs->m2s_q.q_sw_ctrl;
else
q_sw_ctrl_reg = &udma_q->q_regs->s2m_q.q_sw_ctrl;
al_reg_write32(q_sw_ctrl_reg, UDMA_M2S_Q_SW_CTRL_RST_Q);
return 0;
}
/*
* return (by reference) a pointer to a specific queue date structure.
*/
int al_udma_q_handle_get(struct al_udma *udma, uint32_t qid,
struct al_udma_q **q_handle)
{
al_assert(udma);
al_assert(q_handle);
if (unlikely(qid >= udma->num_of_queues)) {
al_err("udma [%s]: invalid queue id (%d)\n", udma->name, qid);
return -EINVAL;
}
*q_handle = &udma->udma_q[qid];
return 0;
}
/*
* Change the UDMA's state
*/
int al_udma_state_set(struct al_udma *udma, enum al_udma_state state)
{
uint32_t reg;
al_assert(udma != NULL);
if (state == udma->state)
al_dbg("udma [%s]: requested state identical to "
"current state (%d)\n", udma->name, state);
al_dbg("udma [%s]: change state from (%s) to (%s)\n",
udma->name, al_udma_states_name[udma->state],
al_udma_states_name[state]);
reg = 0;
switch (state) {
case UDMA_DISABLE:
reg |= UDMA_M2S_CHANGE_STATE_DIS;
break;
case UDMA_NORMAL:
reg |= UDMA_M2S_CHANGE_STATE_NORMAL;
break;
case UDMA_ABORT:
reg |= UDMA_M2S_CHANGE_STATE_ABORT;
break;
default:
al_err("udma: invalid state (%d)\n", state);
return -EINVAL;
}
if (udma->type == UDMA_TX)
al_reg_write32(&udma->udma_regs->m2s.m2s.change_state, reg);
else
al_reg_write32(&udma->udma_regs->s2m.s2m.change_state, reg);
udma->state = state;
return 0;
}
/*
* return the current UDMA hardware state
*/
enum al_udma_state al_udma_state_get(struct al_udma *udma)
{
uint32_t state_reg;
uint32_t comp_ctrl;
uint32_t stream_if;
uint32_t data_rd;
uint32_t desc_pref;
if (udma->type == UDMA_TX)
state_reg = al_reg_read32(&udma->udma_regs->m2s.m2s.state);
else
state_reg = al_reg_read32(&udma->udma_regs->s2m.s2m.state);
comp_ctrl = AL_REG_FIELD_GET(state_reg,
UDMA_M2S_STATE_COMP_CTRL_MASK,
UDMA_M2S_STATE_COMP_CTRL_SHIFT);
stream_if = AL_REG_FIELD_GET(state_reg,
UDMA_M2S_STATE_STREAM_IF_MASK,
UDMA_M2S_STATE_STREAM_IF_SHIFT);
data_rd = AL_REG_FIELD_GET(state_reg,
UDMA_M2S_STATE_DATA_RD_CTRL_MASK,
UDMA_M2S_STATE_DATA_RD_CTRL_SHIFT);
desc_pref = AL_REG_FIELD_GET(state_reg,
UDMA_M2S_STATE_DESC_PREF_MASK,
UDMA_M2S_STATE_DESC_PREF_SHIFT);
al_assert(comp_ctrl != UDMA_STATE_RESERVED);
al_assert(stream_if != UDMA_STATE_RESERVED);
al_assert(data_rd != UDMA_STATE_RESERVED);
al_assert(desc_pref != UDMA_STATE_RESERVED);
/* if any of the states is abort then return abort */
if ((comp_ctrl == UDMA_STATE_ABORT) || (stream_if == UDMA_STATE_ABORT)
|| (data_rd == UDMA_STATE_ABORT)
|| (desc_pref == UDMA_STATE_ABORT))
return UDMA_ABORT;
/* if any of the states is normal then return normal */
if ((comp_ctrl == UDMA_STATE_NORMAL)
|| (stream_if == UDMA_STATE_NORMAL)
|| (data_rd == UDMA_STATE_NORMAL)
|| (desc_pref == UDMA_STATE_NORMAL))
return UDMA_NORMAL;
return UDMA_IDLE;
}
/*
* Action handling
*/
/*
* get next completed packet from completion ring of the queue
*/
uint32_t al_udma_cdesc_packet_get(
struct al_udma_q *udma_q,
volatile union al_udma_cdesc **cdesc)
{
uint32_t count;
volatile union al_udma_cdesc *curr;
uint32_t comp_flags;
/* this function requires the completion ring update */
al_assert(!(udma_q->flags & AL_UDMA_Q_FLAGS_NO_COMP_UPDATE));
/* comp_head points to the last comp desc that was processed */
curr = udma_q->comp_head_ptr;
comp_flags = swap32_from_le(curr->al_desc_comp_tx.ctrl_meta);
/* check if the completion descriptor is new */
if (unlikely(al_udma_new_cdesc(udma_q, comp_flags) == AL_FALSE))
return 0;
/* if new desc found, increment the current packets descriptors */
count = udma_q->pkt_crnt_descs + 1;
while (!cdesc_is_last(comp_flags)) {
curr = al_cdesc_next_update(udma_q, curr);
comp_flags = swap32_from_le(curr->al_desc_comp_tx.ctrl_meta);
if (unlikely(al_udma_new_cdesc(udma_q, comp_flags)
== AL_FALSE)) {
/* the current packet here doesn't have all */
/* descriptors completed. log the current desc */
/* location and number of completed descriptors so */
/* far. then return */
udma_q->pkt_crnt_descs = count;
udma_q->comp_head_ptr = curr;
return 0;
}
count++;
/* check against max descs per packet. */
al_assert(count <= udma_q->size);
}
/* return back the first descriptor of the packet */
*cdesc = al_udma_cdesc_idx_to_ptr(udma_q, udma_q->next_cdesc_idx);
udma_q->pkt_crnt_descs = 0;
udma_q->comp_head_ptr = al_cdesc_next_update(udma_q, curr);
al_dbg("udma [%s %d]: packet completed. first desc %p (ixd 0x%x)"
" descs %d\n", udma_q->udma->name, udma_q->qid, *cdesc,
udma_q->next_cdesc_idx, count);
return count;
}
/** @} end of UDMA group */

View File

@ -0,0 +1,104 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_udma_regs.h
*
* @brief udma registers definition
*
*
*/
#ifndef __AL_HAL_UDMA_REG_H
#define __AL_HAL_UDMA_REG_H
#include "al_hal_udma_regs_m2s.h"
#include "al_hal_udma_regs_s2m.h"
#include "al_hal_udma_regs_gen.h"
#define AL_UDMA_REV_ID_REV0 0
#define AL_UDMA_REV_ID_REV1 1
#define AL_UDMA_REV_ID_REV2 2
#ifdef __cplusplus
extern "C" {
#endif
/** UDMA registers, either m2s or s2m */
union udma_regs {
struct udma_m2s_regs m2s;
struct udma_s2m_regs s2m;
};
struct unit_regs {
struct udma_m2s_regs m2s;
uint32_t rsrvd0[(0x10000 - sizeof(struct udma_m2s_regs)) >> 2];
struct udma_s2m_regs s2m;
uint32_t rsrvd1[((0x1C000 - 0x10000) - sizeof(struct udma_s2m_regs)) >> 2];
struct udma_gen_regs gen;
};
/** UDMA submission and completion registers, M2S and S2M UDMAs have same stucture */
struct udma_rings_regs {
uint32_t rsrvd0[8];
uint32_t cfg; /* Descriptor ring configuration */
uint32_t status; /* Descriptor ring status and information */
uint32_t drbp_low; /* Descriptor Ring Base Pointer [31:4] */
uint32_t drbp_high; /* Descriptor Ring Base Pointer [63:32] */
uint32_t drl; /* Descriptor Ring Length[23:2] */
uint32_t drhp; /* Descriptor Ring Head Pointer */
uint32_t drtp_inc; /* Descriptor Tail Pointer increment */
uint32_t drtp; /* Descriptor Tail Pointer */
uint32_t dcp; /* Descriptor Current Pointer */
uint32_t crbp_low; /* Completion Ring Base Pointer [31:4] */
uint32_t crbp_high; /* Completion Ring Base Pointer [63:32] */
uint32_t crhp; /* Completion Ring Head Pointer */
uint32_t crhp_internal; /* Completion Ring Head Pointer internal, before AX ... */
};
/** M2S and S2M generic structure of Q registers */
union udma_q_regs {
struct udma_rings_regs rings;
struct udma_m2s_q m2s_q;
struct udma_s2m_q s2m_q;
};
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_UDMA_REG_H */
/** @} end of UDMA group */

View File

@ -0,0 +1,414 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @file al_hal_udma_regs_gen.h
*
* @brief C Header file for the UDMA general registers
*
*/
#ifndef __AL_HAL_UDMA_GEN_REG_H
#define __AL_HAL_UDMA_GEN_REG_H
#include "al_hal_udma_iofic_regs.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct udma_gen_dma_misc {
/* [0x0] Reserved register for the interrupt controller */
uint32_t int_cfg;
/* [0x4] Revision register */
uint32_t revision;
/* [0x8] Reserved for future use */
uint32_t general_cfg_1;
/* [0xc] Reserved for future use */
uint32_t general_cfg_2;
/* [0x10] Reserved for future use */
uint32_t general_cfg_3;
/* [0x14] Reserved for future use */
uint32_t general_cfg_4;
/* [0x18] General timer configuration */
uint32_t general_cfg_5;
uint32_t rsrvd[57];
};
struct udma_gen_mailbox {
/*
* [0x0] Mailbox interrupt generator.
* Generates interrupt to neighbor DMA
*/
uint32_t interrupt;
/* [0x4] Mailbox message data out */
uint32_t msg_out;
/* [0x8] Mailbox message data in */
uint32_t msg_in;
uint32_t rsrvd[13];
};
struct udma_gen_axi {
/* [0x0] Configuration of the AXI masters */
uint32_t cfg_1;
/* [0x4] Configuration of the AXI masters */
uint32_t cfg_2;
/* [0x8] Configuration of the AXI masters. Endianess configuration */
uint32_t endian_cfg;
uint32_t rsrvd[61];
};
struct udma_gen_sram_ctrl {
/* [0x0] Timing configuration */
uint32_t timing;
};
struct udma_gen_vmid {
/* [0x0] VMID control */
uint32_t cfg_vmid_0;
/* [0x4] TX queue 0/1 VMID */
uint32_t cfg_vmid_1;
/* [0x8] TX queue 2/3 VMID */
uint32_t cfg_vmid_2;
/* [0xc] RX queue 0/1 VMID */
uint32_t cfg_vmid_3;
/* [0x10] RX queue 2/3 VMID */
uint32_t cfg_vmid_4;
};
struct udma_gen_vmaddr {
/* [0x0] TX queue 0/1 VMADDR */
uint32_t cfg_vmaddr_0;
/* [0x4] TX queue 2/3 VMADDR */
uint32_t cfg_vmaddr_1;
/* [0x8] RX queue 0/1 VMADDR */
uint32_t cfg_vmaddr_2;
/* [0xc] RX queue 2/3 VMADDR */
uint32_t cfg_vmaddr_3;
};
struct udma_gen_vmpr {
/* [0x0] TX VMPR control */
uint32_t cfg_vmpr_0;
/* [0x4] TX VMPR Address High Regsiter */
uint32_t cfg_vmpr_1;
/* [0x8] TX queue VMID values */
uint32_t cfg_vmpr_2;
/* [0xc] TX queue VMID values */
uint32_t cfg_vmpr_3;
/* [0x10] RX VMPR control */
uint32_t cfg_vmpr_4;
/* [0x14] RX VMPR Buffer2 MSB address */
uint32_t cfg_vmpr_5;
/* [0x18] RX queue VMID values */
uint32_t cfg_vmpr_6;
/* [0x1c] RX queue BUF1 VMID values */
uint32_t cfg_vmpr_7;
/* [0x20] RX queue BUF2 VMID values */
uint32_t cfg_vmpr_8;
/* [0x24] RX queue Direct Data Placement VMID values */
uint32_t cfg_vmpr_9;
/* [0x28] RX VMPR BUF1 Address High Regsiter */
uint32_t cfg_vmpr_10;
/* [0x2c] RX VMPR BUF2 Address High Regsiter */
uint32_t cfg_vmpr_11;
/* [0x30] RX VMPR DDP Address High Regsiter */
uint32_t cfg_vmpr_12;
uint32_t rsrvd[3];
};
struct udma_gen_regs {
struct udma_iofic_regs interrupt_regs; /* [0x0000] */
struct udma_gen_dma_misc dma_misc; /* [0x2080] */
struct udma_gen_mailbox mailbox[4]; /* [0x2180] */
struct udma_gen_axi axi; /* [0x2280] */
struct udma_gen_sram_ctrl sram_ctrl[25]; /* [0x2380] */
uint32_t rsrvd_1[2];
struct udma_gen_vmid vmid; /* [0x23ec] */
struct udma_gen_vmaddr vmaddr; /* [0x2400] */
uint32_t rsrvd_2[252];
struct udma_gen_vmpr vmpr[4]; /* [0x2800] */
};
/*
* Registers Fields
*/
/**** int_cfg register ****/
/*
* MSIX data width
* 1 - 64 bit
* 0 32 bit
*/
#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_64 (1 << 0)
/* General configuration */
#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_3_1_MASK 0x0000000E
#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_3_1_SHIFT 1
/* MSIx AXI QoS */
#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_AXI_QOS_MASK 0x00000070
#define UDMA_GEN_DMA_MISC_INT_CFG_MSIX_AXI_QOS_SHIFT 4
#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_31_7_MASK 0xFFFFFF80
#define UDMA_GEN_DMA_MISC_INT_CFG_RESERVED_31_7_SHIFT 7
/**** revision register ****/
/* Design programming interface revision ID */
#define UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_MASK 0x00000FFF
#define UDMA_GEN_DMA_MISC_REVISION_PROGRAMMING_ID_SHIFT 0
/* Design minor revision ID */
#define UDMA_GEN_DMA_MISC_REVISION_MINOR_ID_MASK 0x00FFF000
#define UDMA_GEN_DMA_MISC_REVISION_MINOR_ID_SHIFT 12
/* Design major revision ID */
#define UDMA_GEN_DMA_MISC_REVISION_MAJOR_ID_MASK 0xFF000000
#define UDMA_GEN_DMA_MISC_REVISION_MAJOR_ID_SHIFT 24
/**** Interrupt register ****/
/* Generate interrupt to another DMA */
#define UDMA_GEN_MAILBOX_INTERRUPT_SET (1 << 0)
/**** cfg_2 register ****/
/*
* Enable arbitration promotion.
* Increment master priority after configured number of arbitration cycles
*/
#define UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_MASK 0x0000000F
#define UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_SHIFT 0
/**** endian_cfg register ****/
/* Swap M2S descriptor read and completion descriptor write. */
#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC (1 << 0)
/* Swap M2S data read. */
#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA (1 << 1)
/* Swap S2M descriptor read and completion descriptor write. */
#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC (1 << 2)
/* Swap S2M data write. */
#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA (1 << 3)
/*
* Swap 32 or 64 bit mode:
* 0 - Swap groups of 4 bytes
* 1 - Swap groups of 8 bytes
*/
#define UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN (1 << 4)
/**** timing register ****/
/* Write margin */
#define UDMA_GEN_SRAM_CTRL_TIMING_RMA_MASK 0x0000000F
#define UDMA_GEN_SRAM_CTRL_TIMING_RMA_SHIFT 0
/* Write margin enable */
#define UDMA_GEN_SRAM_CTRL_TIMING_RMEA (1 << 8)
/* Read margin */
#define UDMA_GEN_SRAM_CTRL_TIMING_RMB_MASK 0x000F0000
#define UDMA_GEN_SRAM_CTRL_TIMING_RMB_SHIFT 16
/* Read margin enable */
#define UDMA_GEN_SRAM_CTRL_TIMING_RMEB (1 << 24)
/**** cfg_vmid_0 register ****/
/* For M2S queues 3:0, enable usage of the VMID from the buffer address 63:56 */
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_MASK 0x0000000F
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_DESC_EN_SHIFT 0
/*
* For M2S queues 3:0, enable usage of the VMID from the configuration register
* (cfg_vmid_1/2 used for M2S queue_x)
*/
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_MASK 0x000000F0
#define UDMA_GEN_VMID_CFG_VMID_0_TX_Q_VMID_QUEUE_EN_SHIFT 4
/* use VMID_n [7:0] from MSI-X Controller for MSI-X message */
#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_SEL (1 << 8)
/* Enable write to all VMID_n registers in the MSI-X Controller */
#define UDMA_GEN_VMID_CFG_VMID_0_MSIX_VMID_ACCESS_EN (1 << 9)
/* For S2M queues 3:0, enable usage of the VMID from the buffer address 63:56 */
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_MASK 0x000F0000
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_DESC_EN_SHIFT 16
/*
* For S2M queues 3:0, enable usage of the VMID from the configuration register
* (cfg_vmid_3/4 used for M2S queue_x)
*/
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_MASK 0x00F00000
#define UDMA_GEN_VMID_CFG_VMID_0_RX_Q_VMID_QUEUE_EN_SHIFT 20
/**** cfg_vmid_1 register ****/
/* TX queue 0 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_0_VMID_SHIFT 0
/* TX queue 1 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_1_TX_Q_1_VMID_SHIFT 16
/**** cfg_vmid_2 register ****/
/* TX queue 2 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_2_VMID_SHIFT 0
/* TX queue 3 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_2_TX_Q_3_VMID_SHIFT 16
/**** cfg_vmid_3 register ****/
/* RX queue 0 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_0_VMID_SHIFT 0
/* RX queue 1 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_3_RX_Q_1_VMID_SHIFT 16
/**** cfg_vmid_4 register ****/
/* RX queue 2 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_2_VMID_SHIFT 0
/* RX queue 3 VMID value */
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMID_CFG_VMID_4_RX_Q_3_VMID_SHIFT 16
/**** cfg_vmaddr_0 register ****/
/* TX queue 0 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_0_VMADDR_SHIFT 0
/* TX queue 1 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_0_TX_Q_1_VMADDR_SHIFT 16
/**** cfg_vmaddr_1 register ****/
/* TX queue 2 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_2_VMADDR_SHIFT 0
/* TX queue 3 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_1_TX_Q_3_VMADDR_SHIFT 16
/**** cfg_vmaddr_2 register ****/
/* RX queue 0 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_0_VMADDR_SHIFT 0
/* RX queue 1 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_2_RX_Q_1_VMADDR_SHIFT 16
/**** cfg_vmaddr_3 register ****/
/* RX queue 2 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_MASK 0x0000FFFF
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_2_VMADDR_SHIFT 0
/* RX queue 3 VMADDR value */
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_MASK 0xFFFF0000
#define UDMA_GEN_VMADDR_CFG_VMADDR_3_RX_Q_3_VMADDR_SHIFT 16
/**** cfg_vmpr_0 register ****/
/* TX High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_MASK 0x0000003F
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_HISEL_SHIFT 0
/* TX Data VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_DATA_VMID_EN (1 << 7)
/* TX Prefetch VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_PREF_VMID_EN (1 << 28)
/* TX Completions VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_0_TX_Q_CMPL_VMID_EN (1 << 29)
/**** cfg_vmpr_2 register ****/
/* TX queue Prefetch VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_PREF_VMID_SHIFT 0
/* TX queue Completion VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_2_TX_Q_CMPL_VMID_SHIFT 16
/**** cfg_vmpr_3 register ****/
/* TX queue Data VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SHIFT 0
/* TX queue Data VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_3_TX_Q_DATA_VMID_SEL_SHIFT 16
/**** cfg_vmpr_4 register ****/
/* RX Data Buffer1 - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_MASK 0x0000003F
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_HISEL_SHIFT 0
/* RX Data Buffer1 VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF1_VMID_EN (1 << 7)
/* RX Data Buffer2 - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_MASK 0x00003F00
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_HISEL_SHIFT 8
/* RX Data Buffer2 VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_VMID_EN (1 << 15)
/* RX Direct Data Placement - High Address Select Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_MASK 0x003F0000
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_HISEL_SHIFT 16
/* RX Direct Data Placement VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_DDP_VMID_EN (1 << 23)
/* RX Buffer 2 MSB address word selects per bytes, per queue */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_MASK 0x0F000000
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_BUF2_MSB_ADDR_SEL_SHIFT 24
/* RX Prefetch VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_PREF_VMID_EN (1 << 28)
/* RX Completions VMID Enable Per Q */
#define UDMA_GEN_VMPR_CFG_VMPR_4_RX_Q_CMPL_VMID_EN (1 << 29)
/**** cfg_vmpr_6 register ****/
/* RX queue Prefetch VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_PREF_VMID_SHIFT 0
/* RX queue Completion VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_6_RX_Q_CMPL_VMID_SHIFT 16
/**** cfg_vmpr_7 register ****/
/* RX queue Data Buffer 1 VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SHIFT 0
/* RX queue Data Buffer 1 VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_7_RX_Q_BUF1_VMID_SEL_SHIFT 16
/**** cfg_vmpr_8 register ****/
/* RX queue Data Buffer 2 VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SHIFT 0
/* RX queue Data Buffer 2 VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_8_RX_Q_BUF2_VMID_SEL_SHIFT 16
/**** cfg_vmpr_9 register ****/
/* RX queue DDP VMID */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_MASK 0x0000FFFF
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SHIFT 0
/* RX queue DDP VMID select */
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_MASK 0xFFFF0000
#define UDMA_GEN_VMPR_CFG_VMPR_9_RX_Q_DDP_VMID_SEL_SHIFT 16
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_UDMA_GEN_REG_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,998 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @file al_hal_udma_regs_s2m.h
*
* @brief C Header file for the UDMA S2M registers
*
*/
#ifndef __AL_HAL_UDMA_S2M_REG_H
#define __AL_HAL_UDMA_S2M_REG_H
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct udma_axi_s2m {
/* [0x0] Data write master configuration */
uint32_t data_wr_cfg_1;
/* [0x4] Data write master configuration */
uint32_t data_wr_cfg_2;
/* [0x8] Descriptor read master configuration */
uint32_t desc_rd_cfg_4;
/* [0xc] Descriptor read master configuration */
uint32_t desc_rd_cfg_5;
/* [0x10] Completion write master configuration */
uint32_t comp_wr_cfg_1;
/* [0x14] Completion write master configuration */
uint32_t comp_wr_cfg_2;
/* [0x18] Data write master configuration */
uint32_t data_wr_cfg;
/* [0x1c] Descriptors read master configuration */
uint32_t desc_rd_cfg_3;
/* [0x20] Completion descriptors write master configuration */
uint32_t desc_wr_cfg_1;
/* [0x24] AXI outstanding read configuration */
uint32_t ostand_cfg_rd;
/* [0x28] AXI outstanding write configuration */
uint32_t ostand_cfg_wr;
uint32_t rsrvd[53];
};
struct udma_s2m {
/*
* [0x0] DMA state
* 00 - No pending tasks
* 01 Normal (active)
* 10 Abort (error condition)
* 11 Reserved
*/
uint32_t state;
/* [0x4] CPU request to change DMA state */
uint32_t change_state;
uint32_t rsrvd_0;
/*
* [0xc] S2M DMA error log mask.
* Each error has an interrupt controller cause bit.
* This register determines if these errors cause the S2M DMA to log the
* error condition.
* 0 - Log is enable
* 1 - Log is masked.
*/
uint32_t err_log_mask;
uint32_t rsrvd_1;
/*
* [0x14] DMA header log
* Sample the packet header that caused the error
*/
uint32_t log_0;
/*
* [0x18] DMA header log
* Sample the packet header that caused the error.
*/
uint32_t log_1;
/*
* [0x1c] DMA header log
* Sample the packet header that caused the error.
*/
uint32_t log_2;
/*
* [0x20] DMA header log
* Sample the packet header that caused the error
*/
uint32_t log_3;
/* [0x24] DMA clear error log */
uint32_t clear_err_log;
/* [0x28] S2M stream data FIFO status */
uint32_t s_data_fifo_status;
/* [0x2c] S2M stream header FIFO status */
uint32_t s_header_fifo_status;
/* [0x30] S2M AXI data FIFO status */
uint32_t axi_data_fifo_status;
/* [0x34] S2M unack FIFO status */
uint32_t unack_fifo_status;
/* [0x38] Select queue for debug */
uint32_t indirect_ctrl;
/*
* [0x3c] S2M prefetch FIFO status.
* Status of the selected queue in S2M_indirect_ctrl
*/
uint32_t sel_pref_fifo_status;
/*
* [0x40] S2M completion FIFO status.
* Status of the selected queue in S2M_indirect_ctrl
*/
uint32_t sel_comp_fifo_status;
/* [0x44] S2M state machine and FIFO clear control */
uint32_t clear_ctrl;
/* [0x48] S2M Misc Check enable */
uint32_t check_en;
/* [0x4c] S2M FIFO enable control, internal */
uint32_t fifo_en;
/* [0x50] Stream interface configuration */
uint32_t stream_cfg;
uint32_t rsrvd[43];
};
struct udma_s2m_rd {
/* [0x0] S2M descriptor prefetch configuration */
uint32_t desc_pref_cfg_1;
/* [0x4] S2M descriptor prefetch configuration */
uint32_t desc_pref_cfg_2;
/* [0x8] S2M descriptor prefetch configuration */
uint32_t desc_pref_cfg_3;
/* [0xc] S2M descriptor prefetch configuration */
uint32_t desc_pref_cfg_4;
uint32_t rsrvd[12];
};
struct udma_s2m_wr {
/* [0x0] Stream data FIFO configuration */
uint32_t data_cfg_1;
/* [0x4] Data write configuration */
uint32_t data_cfg_2;
uint32_t rsrvd[14];
};
struct udma_s2m_comp {
/* [0x0] Completion controller configuration */
uint32_t cfg_1c;
/* [0x4] Completion controller configuration */
uint32_t cfg_2c;
uint32_t rsrvd_0;
/* [0xc] Completion controller application acknowledge configuration */
uint32_t cfg_application_ack;
uint32_t rsrvd[12];
};
struct udma_s2m_stat {
uint32_t rsrvd_0;
/* [0x4] Number of dropped packets */
uint32_t drop_pkt;
/*
* [0x8] Counting the net length of the data buffers [64-bit]
* Should be read before rx_bytes_high
*/
uint32_t rx_bytes_low;
/*
* [0xc] Counting the net length of the data buffers [64-bit]
* Should be read after tx_bytes_low (value is sampled when reading
* Should be read before rx_bytes_low
*/
uint32_t rx_bytes_high;
/* [0x10] Total number of descriptors read from the host memory */
uint32_t prefed_desc;
/* [0x14] Number of packets written into the completion ring */
uint32_t comp_pkt;
/* [0x18] Number of descriptors written into the completion ring */
uint32_t comp_desc;
/*
* [0x1c] Number of acknowledged packets.
* (acknowledge sent to the stream interface)
*/
uint32_t ack_pkts;
uint32_t rsrvd[56];
};
struct udma_s2m_feature {
/*
* [0x0] S2M Feature register
* S2M instantiation parameters
*/
uint32_t reg_1;
/* [0x4] Reserved S2M feature register */
uint32_t reg_2;
/*
* [0x8] S2M Feature register
* S2M instantiation parameters
*/
uint32_t reg_3;
/*
* [0xc] S2M Feature register.
* S2M instantiation parameters.
*/
uint32_t reg_4;
/*
* [0x10] S2M Feature register.
* S2M instantiation parameters.
*/
uint32_t reg_5;
/* [0x14] S2M Feature register. S2M instantiation parameters. */
uint32_t reg_6;
uint32_t rsrvd[58];
};
struct udma_s2m_q {
uint32_t rsrvd_0[8];
/* [0x20] S2M Descriptor ring configuration */
uint32_t cfg;
/* [0x24] S2M Descriptor ring status and information */
uint32_t status;
/* [0x28] Rx Descriptor Ring Base Pointer [31:4] */
uint32_t rdrbp_low;
/* [0x2c] Rx Descriptor Ring Base Pointer [63:32] */
uint32_t rdrbp_high;
/*
* [0x30] Rx Descriptor Ring Length[23:2]
*/
uint32_t rdrl;
/* [0x34] RX Descriptor Ring Head Pointer */
uint32_t rdrhp;
/* [0x38] Rx Descriptor Tail Pointer increment */
uint32_t rdrtp_inc;
/* [0x3c] Rx Descriptor Tail Pointer */
uint32_t rdrtp;
/* [0x40] RX Descriptor Current Pointer */
uint32_t rdcp;
/* [0x44] Rx Completion Ring Base Pointer [31:4] */
uint32_t rcrbp_low;
/* [0x48] Rx Completion Ring Base Pointer [63:32] */
uint32_t rcrbp_high;
/* [0x4c] Rx Completion Ring Head Pointer */
uint32_t rcrhp;
/*
* [0x50] RX Completion Ring Head Pointer internal.
* (Before the coalescing FIFO)
*/
uint32_t rcrhp_internal;
/* [0x54] Completion controller configuration for the queue */
uint32_t comp_cfg;
/* [0x58] Completion controller configuration for the queue */
uint32_t comp_cfg_2;
/* [0x5c] Packet handler configuration */
uint32_t pkt_cfg;
/* [0x60] Queue QoS configuration */
uint32_t qos_cfg;
/* [0x64] DMB software control */
uint32_t q_sw_ctrl;
/* [0x68] Number of S2M Rx packets after completion */
uint32_t q_rx_pkt;
uint32_t rsrvd[997];
};
struct udma_s2m_regs {
uint32_t rsrvd_0[64];
struct udma_axi_s2m axi_s2m; /* [0x100] */
struct udma_s2m s2m; /* [0x200] */
struct udma_s2m_rd s2m_rd; /* [0x300] */
struct udma_s2m_wr s2m_wr; /* [0x340] */
struct udma_s2m_comp s2m_comp; /* [0x380] */
uint32_t rsrvd_1[80];
struct udma_s2m_stat s2m_stat; /* [0x500] */
struct udma_s2m_feature s2m_feature; /* [0x600] */
uint32_t rsrvd_2[576];
struct udma_s2m_q s2m_q[4]; /* [0x1000] */
};
/*
* Registers Fields
*/
/**** data_wr_cfg_1 register ****/
/* AXI write ID (AWID) */
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWID_MASK 0x000000FF
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWID_SHIFT 0
/* Cache Type */
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWCACHE_MASK 0x000F0000
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWCACHE_SHIFT 16
/* Burst type */
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWBURST_MASK 0x03000000
#define UDMA_AXI_S2M_DATA_WR_CFG_1_AWBURST_SHIFT 24
/**** data_wr_cfg_2 register ****/
/* User extension */
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWUSER_MASK 0x000FFFFF
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWUSER_SHIFT 0
/* Bus size, 128-bit */
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWSIZE_MASK 0x00700000
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWSIZE_SHIFT 20
/*
* AXI Master QoS.
* Used for arbitration between AXI masters
*/
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWQOS_MASK 0x07000000
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWQOS_SHIFT 24
/* Protection Type */
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWPROT_MASK 0x70000000
#define UDMA_AXI_S2M_DATA_WR_CFG_2_AWPROT_SHIFT 28
/**** desc_rd_cfg_4 register ****/
/* AXI read ID (ARID) */
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARID_MASK 0x000000FF
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARID_SHIFT 0
/* Cache Type */
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARCACHE_MASK 0x000F0000
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARCACHE_SHIFT 16
/* Burst type */
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARBURST_MASK 0x03000000
#define UDMA_AXI_S2M_DESC_RD_CFG_4_ARBURST_SHIFT 24
/**** desc_rd_cfg_5 register ****/
/* User extension */
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARUSER_MASK 0x000FFFFF
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARUSER_SHIFT 0
/* Bus size, 128-bit */
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARSIZE_MASK 0x00700000
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARSIZE_SHIFT 20
/*
* AXI Master QoS.
* Used for arbitration between AXI masters
*/
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARQOS_MASK 0x07000000
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARQOS_SHIFT 24
/* Protection Type */
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARPROT_MASK 0x70000000
#define UDMA_AXI_S2M_DESC_RD_CFG_5_ARPROT_SHIFT 28
/**** comp_wr_cfg_1 register ****/
/* AXI write ID (AWID) */
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK 0x000000FF
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_SHIFT 0
/* Cache Type */
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK 0x000F0000
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_SHIFT 16
/* Burst type */
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK 0x03000000
#define UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_SHIFT 24
/**** comp_wr_cfg_2 register ****/
/* User extension */
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK 0x000FFFFF
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_SHIFT 0
/* Bus size, 128-bit */
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK 0x00700000
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_SHIFT 20
/*
* AXI Master QoS.
* Used for arbitration between AXI masters
*/
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK 0x07000000
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_SHIFT 24
/* Protection Type */
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK 0x70000000
#define UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_SHIFT 28
/**** data_wr_cfg register ****/
/*
* Defines the maximum number of AXI beats for a single AXI burst. This value is
* used for the burst split decision.
*/
#define UDMA_AXI_S2M_DATA_WR_CFG_MAX_AXI_BEATS_MASK 0x000000FF
#define UDMA_AXI_S2M_DATA_WR_CFG_MAX_AXI_BEATS_SHIFT 0
/**** desc_rd_cfg_3 register ****/
/*
* Defines the maximum number of AXI beats for a single AXI burst. This value is
* used for the burst split decision.
*/
#define UDMA_AXI_S2M_DESC_RD_CFG_3_MAX_AXI_BEATS_MASK 0x000000FF
#define UDMA_AXI_S2M_DESC_RD_CFG_3_MAX_AXI_BEATS_SHIFT 0
/*
* Enables breaking descriptor read request.
* Aligned to max_AXI_beats when the total read size is less than max_AXI_beats.
*/
#define UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY (1 << 16)
/**** desc_wr_cfg_1 register ****/
/*
* Defines the maximum number of AXI beats for a single AXI burst. This value is
* used for the burst split decision.
*/
#define UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK 0x000000FF
#define UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT 0
/*
* Minimum burst for writing completion descriptors.
* (AXI beats).
* Value must be aligned to cache lines (64 bytes).
* Default value is 2 cache lines, 8 beats.
*/
#define UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK 0x00FF0000
#define UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT 16
/**** ostand_cfg_rd register ****/
/*
* Maximum number of outstanding descriptor reads to the AXI.
* (AXI transactions).
*/
#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK 0x0000003F
#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_SHIFT 0
/* Maximum number of outstanding stream acknowledges. */
#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK 0x001F0000
#define UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_SHIFT 16
/**** ostand_cfg_wr register ****/
/*
* Maximum number of outstanding data writes to the AXI.
* (AXI transactions).
*/
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK 0x0000003F
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_SHIFT 0
/*
* Maximum number of outstanding data beats for data write to AXI.
* (AXI beats).
*/
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK 0x0000FF00
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_SHIFT 8
/*
* Maximum number of outstanding descriptor writes to the AXI.
* (AXI transactions).
*/
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK 0x003F0000
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_SHIFT 16
/*
* Maximum number of outstanding data beats for descriptor write to AXI.
* (AXI beats).
*/
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK 0xFF000000
#define UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_SHIFT 24
/**** state register ****/
#define UDMA_S2M_STATE_COMP_CTRL_MASK 0x00000003
#define UDMA_S2M_STATE_COMP_CTRL_SHIFT 0
#define UDMA_S2M_STATE_STREAM_IF_MASK 0x00000030
#define UDMA_S2M_STATE_STREAM_IF_SHIFT 4
#define UDMA_S2M_STATE_DATA_WR_CTRL_MASK 0x00000300
#define UDMA_S2M_STATE_DATA_WR_CTRL_SHIFT 8
#define UDMA_S2M_STATE_DESC_PREF_MASK 0x00003000
#define UDMA_S2M_STATE_DESC_PREF_SHIFT 12
#define UDMA_S2M_STATE_AXI_WR_DATA_MASK 0x00030000
#define UDMA_S2M_STATE_AXI_WR_DATA_SHIFT 16
/**** change_state register ****/
/* Start normal operation */
#define UDMA_S2M_CHANGE_STATE_NORMAL (1 << 0)
/* Stop normal operation */
#define UDMA_S2M_CHANGE_STATE_DIS (1 << 1)
/*
* Stop all machines.
* (Prefetch, scheduling, completion and stream interface)
*/
#define UDMA_S2M_CHANGE_STATE_ABORT (1 << 2)
/**** clear_err_log register ****/
/* Clear error log */
#define UDMA_S2M_CLEAR_ERR_LOG_CLEAR (1 << 0)
/**** s_data_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_S_DATA_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_S_DATA_FIFO_STATUS_USED_SHIFT 0
/* FIFO empty indication */
#define UDMA_S2M_S_DATA_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_S_DATA_FIFO_STATUS_FULL (1 << 28)
/**** s_header_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_S_HEADER_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_S_HEADER_FIFO_STATUS_USED_SHIFT 0
/* FIFO empty indication */
#define UDMA_S2M_S_HEADER_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_S_HEADER_FIFO_STATUS_FULL (1 << 28)
/**** axi_data_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_AXI_DATA_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_AXI_DATA_FIFO_STATUS_USED_SHIFT 0
/* FIFO empty indication */
#define UDMA_S2M_AXI_DATA_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_AXI_DATA_FIFO_STATUS_FULL (1 << 28)
/**** unack_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_UNACK_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_UNACK_FIFO_STATUS_USED_SHIFT 0
/* FIFO empty indication */
#define UDMA_S2M_UNACK_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_UNACK_FIFO_STATUS_FULL (1 << 28)
/**** indirect_ctrl register ****/
/* Selected queue for status read */
#define UDMA_S2M_INDIRECT_CTRL_Q_NUM_MASK 0x00000FFF
#define UDMA_S2M_INDIRECT_CTRL_Q_NUM_SHIFT 0
/**** sel_pref_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_SEL_PREF_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_SEL_PREF_FIFO_STATUS_USED_SHIFT 0
/* FIFO empty indication */
#define UDMA_S2M_SEL_PREF_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_SEL_PREF_FIFO_STATUS_FULL (1 << 28)
/**** sel_comp_fifo_status register ****/
/* FIFO used indication */
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_USED_MASK 0x0000FFFF
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_USED_SHIFT 0
/* Coalescing ACTIVE FSM state indication. */
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_COAL_ACTIVE_STATE_MASK 0x00300000
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_COAL_ACTIVE_STATE_SHIFT 20
/* FIFO empty indication */
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_EMPTY (1 << 24)
/* FIFO full indication */
#define UDMA_S2M_SEL_COMP_FIFO_STATUS_FULL (1 << 28)
/**** stream_cfg register ****/
/*
* Disables the stream interface operation.
* Changing to 1 stops at the end of packet reception.
*/
#define UDMA_S2M_STREAM_CFG_DISABLE (1 << 0)
/*
* Flush the stream interface operation.
* Changing to 1 stops at the end of packet reception and assert ready to the
* stream I/F.
*/
#define UDMA_S2M_STREAM_CFG_FLUSH (1 << 4)
/* Stop descriptor prefetch when the stream is disabled and the S2M is idle. */
#define UDMA_S2M_STREAM_CFG_STOP_PREFETCH (1 << 8)
/**** desc_pref_cfg_1 register ****/
/*
* Size of the descriptor prefetch FIFO.
* (descriptors)
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK 0x000000FF
#define UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT 0
/**** desc_pref_cfg_2 register ****/
/* Enable promotion of the current queue in progress */
#define UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION (1 << 0)
/* Force promotion of the current queue in progress */
#define UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION (1 << 1)
/* Enable prefetch prediction of next packet in line. */
#define UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION (1 << 2)
/*
* Threshold for queue promotion.
* Queue is promoted for prefetch if there are less descriptors in the prefetch
* FIFO than the threshold
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK 0x0000FF00
#define UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_SHIFT 8
/*
* Force RR arbitration in the prefetch arbiter.
* 0 - Standard arbitration based on queue QoS
* 1 - Force round robin arbitration
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR (1 << 16)
/**** desc_pref_cfg_3 register ****/
/*
* Minimum descriptor burst size when prefetch FIFO level is below the
* descriptor prefetch threshold
* (must be 1)
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK 0x0000000F
#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT 0
/*
* Minimum descriptor burst size when prefetch FIFO level is above the
* descriptor prefetch threshold
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK 0x000000F0
#define UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT 4
/*
* Descriptor fetch threshold.
* Used as a threshold to determine the allowed minimum descriptor burst size.
* (Must be at least "max_desc_per_pkt")
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK 0x0000FF00
#define UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT 8
/**** desc_pref_cfg_4 register ****/
/*
* Used as a threshold for generating almost FULL indication to the application
*/
#define UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK 0x000000FF
#define UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_SHIFT 0
/**** data_cfg_1 register ****/
/*
* Maximum number of data beats in the data write FIFO.
* Defined based on data FIFO size
* (default FIFO size 512B 32 beats)
*/
#define UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK 0x000003FF
#define UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_SHIFT 0
/*
* Maximum number of packets in the data write FIFO.
* Defined based on header FIFO size
*/
#define UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK 0x00FF0000
#define UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_SHIFT 16
/*
* Internal use
* Data FIFO margin
*/
#define UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK 0xFF000000
#define UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_SHIFT 24
/**** data_cfg_2 register ****/
/*
* Drop timer.
* Waiting time for the host to write new descriptor to the queue
* (for the current packet in process)
*/
#define UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK 0x00FFFFFF
#define UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_SHIFT 0
/*
* Drop enable.
* Enable packet drop if there are no available descriptors in the system for
* this queue
*/
#define UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC (1 << 27)
/*
* Lack of descriptors hint.
* Generate interrupt when a packet is waiting but there are no available
* descriptors in the queue
*/
#define UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC (1 << 28)
/*
* Drop conditions
* Wait until a descriptor is available in the prefetch FIFO or the host before
* dropping packet.
* 1 - Drop if a descriptor is not available in the prefetch.
* 0 - Drop if a descriptor is not available in the system
*/
#define UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF (1 << 29)
/*
* DRAM write optimization
* 0 - Data write with byte enable
* 1 - Data write is always in Full AXI bus width (128 bit)
*/
#define UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE (1 << 30)
/*
* Direct data write address
* 1 - Use buffer 1 instead of buffer 2 when direct data placement is used with
* header split.
* 0 - Use buffer 2 for the header.
*/
#define UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1 (1 << 31)
/**** cfg_1c register ****/
/*
* Completion descriptor size.
* (words)
*/
#define UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK 0x0000000F
#define UDMA_S2M_COMP_CFG_1C_DESC_SIZE_SHIFT 0
/*
* Completion queue counter configuration.
* Completion FIFO in use counter measured in words or descriptors
* 1 - Words
* 0 - Descriptors
*/
#define UDMA_S2M_COMP_CFG_1C_CNT_WORDS (1 << 8)
/*
* Enable promotion of the current queue in progress in the completion write
* scheduler.
*/
#define UDMA_S2M_COMP_CFG_1C_Q_PROMOTION (1 << 12)
/* Force RR arbitration in the completion arbiter */
#define UDMA_S2M_COMP_CFG_1C_FORCE_RR (1 << 16)
/* Minimum number of free completion entries to qualify for promotion */
#define UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK 0xF0000000
#define UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_SHIFT 28
/**** cfg_2c register ****/
/*
* Completion FIFO size.
* (words per queue)
*/
#define UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK 0x00000FFF
#define UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_SHIFT 0
/*
* Unacknowledged FIFO size.
* (descriptors)
*/
#define UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK 0x0FFF0000
#define UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_SHIFT 16
/**** reg_1 register ****/
/*
* Descriptor prefetch FIFO size
* (descriptors)
*/
#define UDMA_S2M_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_MASK 0x000000FF
#define UDMA_S2M_FEATURE_REG_1_DESC_PREFERCH_FIFO_DEPTH_SHIFT 0
/**** reg_3 register ****/
/*
* Maximum number of data beats in the data write FIFO.
* Defined based on data FIFO size
* (default FIFO size 512B 32 beats)
*/
#define UDMA_S2M_FEATURE_REG_3_DATA_FIFO_DEPTH_MASK 0x000003FF
#define UDMA_S2M_FEATURE_REG_3_DATA_FIFO_DEPTH_SHIFT 0
/*
* Maximum number of packets in the data write FIFO.
* Defined based on header FIFO size
*/
#define UDMA_S2M_FEATURE_REG_3_DATA_WR_MAX_PKT_LIMIT_MASK 0x00FF0000
#define UDMA_S2M_FEATURE_REG_3_DATA_WR_MAX_PKT_LIMIT_SHIFT 16
/**** reg_4 register ****/
/*
* Completion FIFO size.
* (words per queue)
*/
#define UDMA_S2M_FEATURE_REG_4_COMP_FIFO_DEPTH_MASK 0x00000FFF
#define UDMA_S2M_FEATURE_REG_4_COMP_FIFO_DEPTH_SHIFT 0
/*
* Unacknowledged FIFO size.
* (descriptors)
*/
#define UDMA_S2M_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_MASK 0x0FFF0000
#define UDMA_S2M_FEATURE_REG_4_COMP_UNACK_FIFO_DEPTH_SHIFT 16
/**** reg_5 register ****/
/* Maximum number of outstanding data writes to the AXI */
#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_WR_OSTAND_MASK 0x0000003F
#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_WR_OSTAND_SHIFT 0
/*
* Maximum number of outstanding data beats for data write to AXI.
* (AXI beats)
*/
#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_BEATS_WR_OSTAND_MASK 0x0000FF00
#define UDMA_S2M_FEATURE_REG_5_MAX_DATA_BEATS_WR_OSTAND_SHIFT 8
/*
* Maximum number of outstanding descriptor reads to the AXI.
* (AXI transactions)
*/
#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_REQ_MASK 0x003F0000
#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_REQ_SHIFT 16
/*
* Maximum number of outstanding data beats for descriptor write to AXI.
* (AXI beats)
*/
#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_MASK 0xFF000000
#define UDMA_S2M_FEATURE_REG_5_MAX_COMP_DATA_WR_OSTAND_SHIFT 24
/**** reg_6 register ****/
/* Maximum number of outstanding descriptor reads to the AXI */
#define UDMA_S2M_FEATURE_REG_6_MAX_DESC_RD_OSTAND_MASK 0x0000003F
#define UDMA_S2M_FEATURE_REG_6_MAX_DESC_RD_OSTAND_SHIFT 0
/* Maximum number of outstanding stream acknowledges */
#define UDMA_S2M_FEATURE_REG_6_MAX_STREAM_ACK_MASK 0x001F0000
#define UDMA_S2M_FEATURE_REG_6_MAX_STREAM_ACK_SHIFT 16
/**** cfg register ****/
/*
* Configure the AXI AWCACHE
* for header write.
*/
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_HDR_MASK 0x0000000F
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_HDR_SHIFT 0
/*
* Configure the AXI AWCACHE
* for data write.
*/
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_DATA_MASK 0x000000F0
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_DATA_SHIFT 4
/*
* Enable operation of this queue.
* Start prefetch.
*/
#define UDMA_S2M_Q_CFG_EN_PREF (1 << 16)
/* Enables the reception of packets from the stream to this queue */
#define UDMA_S2M_Q_CFG_EN_STREAM (1 << 17)
/* Allow prefetch of less than minimum prefetch burst size. */
#define UDMA_S2M_Q_CFG_ALLOW_LT_MIN_PREF (1 << 20)
/*
* Configure the AXI AWCACHE
* for completion descriptor write
*/
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_COMP_MASK 0x0F000000
#define UDMA_S2M_Q_CFG_AXI_AWCACHE_COMP_SHIFT 24
/*
* AXI QoS
* This value is used in AXI transactions associated with this queue and the
* prefetch and completion arbiters.
*/
#define UDMA_S2M_Q_CFG_AXI_QOS_MASK 0x70000000
#define UDMA_S2M_Q_CFG_AXI_QOS_SHIFT 28
/**** status register ****/
/* Indicates how many entries are used in the Queue */
#define UDMA_S2M_Q_STATUS_Q_USED_MASK 0x01FFFFFF
#define UDMA_S2M_Q_STATUS_Q_USED_SHIFT 0
/*
* prefetch status
* 0 prefetch operation is stopped
* 1 prefetch is operational
*/
#define UDMA_S2M_Q_STATUS_PREFETCH (1 << 28)
/*
* Queue receive status
* 0 -queue RX operation is stopped
* 1 RX queue is active and processing packets
*/
#define UDMA_S2M_Q_STATUS_RX (1 << 29)
/*
* Indicates if the queue is full.
* (Used by the host when head pointer equals tail pointer)
*/
#define UDMA_S2M_Q_STATUS_Q_FULL (1 << 31)
/*
* S2M Descriptor Ring Base address [31:4].
* Value of the base address of the S2M descriptor ring
* [3:0] - 0 - 16B alignment is enforced
* ([11:4] should be 0 for 4KB alignment)
*/
#define UDMA_S2M_Q_RDRBP_LOW_ADDR_MASK 0xFFFFFFF0
#define UDMA_S2M_Q_RDRBP_LOW_ADDR_SHIFT 4
/**** RDRL register ****/
/*
* Length of the descriptor ring.
* (descriptors)
* Associated with the ring base address ends at maximum burst size alignment
*/
#define UDMA_S2M_Q_RDRL_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RDRL_OFFSET_SHIFT 0
/**** RDRHP register ****/
/*
* Relative offset of the next descriptor that needs to be read into the
* prefetch FIFO.
* Incremented when the DMA reads valid descriptors from the host memory to the
* prefetch FIFO.
* Note that this is the offset in # of descriptors and not in byte address.
*/
#define UDMA_S2M_Q_RDRHP_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RDRHP_OFFSET_SHIFT 0
/* Ring ID */
#define UDMA_S2M_Q_RDRHP_RING_ID_MASK 0xC0000000
#define UDMA_S2M_Q_RDRHP_RING_ID_SHIFT 30
/**** RDRTP_inc register ****/
/*
* Increments the value in Q_RDRTP with the value written to this field in
* number of descriptors.
*/
#define UDMA_S2M_Q_RDRTP_INC_VAL_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RDRTP_INC_VAL_SHIFT 0
/**** RDRTP register ****/
/*
* Relative offset of the next free descriptor in the host memory.
* Note that this is the offset in # of descriptors and not in byte address.
*/
#define UDMA_S2M_Q_RDRTP_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RDRTP_OFFSET_SHIFT 0
/* Ring ID */
#define UDMA_S2M_Q_RDRTP_RING_ID_MASK 0xC0000000
#define UDMA_S2M_Q_RDRTP_RING_ID_SHIFT 30
/**** RDCP register ****/
/* Relative offset of the first descriptor in the prefetch FIFO. */
#define UDMA_S2M_Q_RDCP_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RDCP_OFFSET_SHIFT 0
/* Ring ID */
#define UDMA_S2M_Q_RDCP_RING_ID_MASK 0xC0000000
#define UDMA_S2M_Q_RDCP_RING_ID_SHIFT 30
/*
* S2M Descriptor Ring Base address [31:4].
* Value of the base address of the S2M descriptor ring
* [3:0] - 0 - 16B alignment is enforced
* ([11:4] Must be 0 for 4KB alignment)
* NOTE:
* Length of the descriptor ring (in descriptors) associated with the ring base
* address ends at maximum burst size alignment
*/
#define UDMA_S2M_Q_RCRBP_LOW_ADDR_MASK 0xFFFFFFF0
#define UDMA_S2M_Q_RCRBP_LOW_ADDR_SHIFT 4
/**** RCRHP register ****/
/*
* Relative offset of the next descriptor that needs to be updated by the
* completion controller.
* Note: This is in descriptors and not in byte address.
*/
#define UDMA_S2M_Q_RCRHP_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RCRHP_OFFSET_SHIFT 0
/* Ring ID */
#define UDMA_S2M_Q_RCRHP_RING_ID_MASK 0xC0000000
#define UDMA_S2M_Q_RCRHP_RING_ID_SHIFT 30
/**** RCRHP_internal register ****/
/*
* Relative offset of the next descriptor that needs to be updated by the
* completion controller.
* Note: This is in descriptors and not in byte address.
*/
#define UDMA_S2M_Q_RCRHP_INTERNAL_OFFSET_MASK 0x00FFFFFF
#define UDMA_S2M_Q_RCRHP_INTERNAL_OFFSET_SHIFT 0
/* Ring ID */
#define UDMA_S2M_Q_RCRHP_INTERNAL_RING_ID_MASK 0xC0000000
#define UDMA_S2M_Q_RCRHP_INTERNAL_RING_ID_SHIFT 30
/**** comp_cfg register ****/
/* Enables writing to the completion ring. */
#define UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE (1 << 0)
/* Disables the completion coalescing function. */
#define UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL (1 << 1)
/* Reserved */
#define UDMA_S2M_Q_COMP_CFG_FIRST_PKT_PROMOTION (1 << 2)
/*
* Buffer 2 location.
* Determines the position of the buffer 2 length in the S2M completion
* descriptor.
* 0 - WORD 1 [31:16]
* 1 - WORD 2 [31:16]
*/
#define UDMA_S2M_Q_COMP_CFG_BUF2_LEN_LOCATION (1 << 3)
/**** pkt_cfg register ****/
/* Header size. (bytes) */
#define UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK 0x0000FFFF
#define UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_SHIFT 0
/* Force header split */
#define UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT (1 << 16)
/* Enable header split. */
#define UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT (1 << 17)
/**** qos_cfg register ****/
/* Queue QoS */
#define UDMA_S2M_QOS_CFG_Q_QOS_MASK 0x000000FF
#define UDMA_S2M_QOS_CFG_Q_QOS_SHIFT 0
/* Reset the tail pointer hardware. */
#define UDMA_S2M_Q_SW_CTRL_RST_TAIL_PTR (1 << 1)
/* Reset the head pointer hardware. */
#define UDMA_S2M_Q_SW_CTRL_RST_HEAD_PTR (1 << 2)
/* Reset the current pointer hardware. */
#define UDMA_S2M_Q_SW_CTRL_RST_CURRENT_PTR (1 << 3)
/* Reset the prefetch FIFO */
#define UDMA_S2M_Q_SW_CTRL_RST_PREFETCH (1 << 4)
/* Reset the queue */
#define UDMA_S2M_Q_SW_CTRL_RST_Q (1 << 8)
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_UDMA_S2M_REG_H */

View File

@ -0,0 +1,314 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_UNIT_ADAPTER_REGS_H__
#define __AL_HAL_UNIT_ADAPTER_REGS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define AL_PCI_COMMAND 0x04 /* 16 bits */
#define AL_PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define AL_PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define AL_PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
#define AL_PCI_BASE_ADDRESS_SPACE_IO 0x01
#define AL_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define AL_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define AL_PCI_BASE_ADDRESS_DEVICE_ID 0x0c
#define AL_PCI_BASE_ADDRESS_0 0x10
#define AL_PCI_BASE_ADDRESS_0_HI 0x14
#define AL_PCI_BASE_ADDRESS_2 0x18
#define AL_PCI_BASE_ADDRESS_2_HI 0x1c
#define AL_PCI_BASE_ADDRESS_4 0x20
#define AL_PCI_BASE_ADDRESS_4_HI 0x24
#define AL_PCI_EXP_ROM_BASE_ADDRESS 0x30
#define AL_PCI_AXI_CFG_AND_CTR_0 0x110
#define AL_PCI_AXI_CFG_AND_CTR_1 0x130
#define AL_PCI_AXI_CFG_AND_CTR_2 0x150
#define AL_PCI_AXI_CFG_AND_CTR_3 0x170
#define AL_PCI_APP_CONTROL 0x220
#define AL_PCI_SRIOV_TOTAL_AND_INITIAL_VFS 0x30c
#define AL_PCI_VF_BASE_ADDRESS_0 0x324
#define AL_PCI_EXP_CAP_BASE 0x40
#define AL_PCI_EXP_DEVCAP 4 /* Device capabilities */
#define AL_PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
#define AL_PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
#define AL_PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
#define AL_PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
#define AL_PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
#define AL_PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
#define AL_PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
#define AL_PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
#define AL_PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */
#define AL_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
#define AL_PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
#define AL_PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
#define AL_PCI_EXP_DEVCTL 8 /* Device Control */
#define AL_PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
#define AL_PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
#define AL_PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
#define AL_PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
#define AL_PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
#define AL_PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define AL_PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
#define AL_PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
#define AL_PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
#define AL_PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
#define AL_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
#define AL_PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
#define AL_PCI_EXP_DEVSTA 0xA /* Device Status */
#define AL_PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
#define AL_PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
#define AL_PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
#define AL_PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
#define AL_PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define AL_PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#define AL_PCI_EXP_LNKCAP 0xC /* Link Capabilities */
#define AL_PCI_EXP_LNKCAP_SLS 0xf /* Supported Link Speeds */
#define AL_PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */
#define AL_PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */
#define AL_PCI_EXP_LNKCAP_MLW 0x3f0 /* Maximum Link Width */
#define AL_PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */
#define AL_PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */
#define AL_PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */
#define AL_PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */
#define AL_PCI_EXP_LNKCAP_SDERC 0x80000 /* Surprise Down Error Reporting Capable */
#define AL_PCI_EXP_LNKCAP_DLLLARC 0x100000 /* Data Link Layer Link Active Reporting Capable */
#define AL_PCI_EXP_LNKCAP_LBNC 0x200000 /* Link Bandwidth Notification Capability */
#define AL_PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */
#define AL_PCI_EXP_LNKCTL 0x10 /* Link Control */
#define AL_PCI_EXP_LNKCTL_LNK_DIS 0x4 /* Link Disable Status */
#define AL_PCI_EXP_LNKCTL_LNK_RTRN 0x5 /* Link Retrain Status */
#define AL_PCI_EXP_LNKSTA 0x12 /* Link Status */
#define AL_PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */
#define AL_PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */
#define AL_PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */
#define AL_PCI_EXP_LNKSTA_CLS_8_0GB 0x03 /* Current Link Speed 8.0GT/s */
#define AL_PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */
#define AL_PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */
#define AL_PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */
#define AL_PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */
#define AL_PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
#define AL_PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */
#define AL_PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */
#define AL_PCI_EXP_LNKCTL2 0x30 /* Link Control 2 */
#define AL_PCI_MSIX_MSGCTRL 0 /* MSIX message control reg */
#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE 0x7ff /* MSIX table size */
#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT 16 /* MSIX table size shift */
#define AL_PCI_MSIX_MSGCTRL_EN 0x80000000 /* MSIX enable */
#define AL_PCI_MSIX_MSGCTRL_MASK 0x40000000 /* MSIX mask */
#define AL_PCI_MSIX_TABLE 0x4 /* MSIX table offset and bar reg */
#define AL_PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* MSIX table offset */
#define AL_PCI_MSIX_TABLE_BAR 0x7 /* MSIX table BAR */
#define AL_PCI_MSIX_PBA 0x8 /* MSIX pba offset and bar reg */
#define AL_PCI_MSIX_PBA_OFFSET 0xfffffff8 /* MSIX pba offset */
#define AL_PCI_MSIX_PBA_BAR 0x7 /* MSIX pba BAR */
/* Adapter power management register 0 */
#define AL_ADAPTER_PM_0 0x80
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_MASK 0xff00
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_SHIFT 8
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_VAL_MSIX 0x90
/* Adapter power management register 1 */
#define AL_ADAPTER_PM_1 0x84
#define AL_ADAPTER_PM_1_PME_EN 0x100 /* PM enable */
#define AL_ADAPTER_PM_1_PWR_STATE_MASK 0x3 /* PM state mask */
#define AL_ADAPTER_PM_1_PWR_STATE_D3 0x3 /* PM D3 state */
/* Sub Master Configuration & Control */
#define AL_ADAPTER_SMCC 0x110
#define AL_ADAPTER_SMCC_CONF_2 0x114
/* Interrupt_Cause register */
#define AL_ADAPTER_INT_CAUSE 0x1B0
#define AL_ADAPTER_INT_CAUSE_WR_ERR AL_BIT(1)
#define AL_ADAPTER_INT_CAUSE_RD_ERR AL_BIT(0)
/* AXI_Master_Write_Error_Attribute_Latch register */
/* AXI_Master_Read_Error_Attribute_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_ATTR 0x1B4
#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR 0x1B8
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_MASK AL_FIELD_MASK(1, 0)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_SHIFT 0
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_MASK AL_FIELD_MASK(4, 2)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_SHIFT 2
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ADDR_TO AL_BIT(8)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_ERR AL_BIT(9)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_TO AL_BIT(10)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ERR_BLK AL_BIT(11)
#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR_RD_PARITY_ERR AL_BIT(12)
/* Interrupt_Cause_mask register */
#define AL_ADAPTER_INT_CAUSE_MASK 0x1BC
#define AL_ADAPTER_INT_CAUSE_MASK_WR_ERR AL_BIT(1)
#define AL_ADAPTER_INT_CAUSE_MASK_RD_ERR AL_BIT(0)
/* AXI_Master_write_error_address_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_LO_LATCH 0x1C0
/* AXI_Master_write_error_address_high_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_HI_LATCH 0x1C4
/* AXI_Master_read_error_address_Latch register */
#define AL_ADAPTER_AXI_MSTR_RD_ERR_LO_LATCH 0x1C8
/* AXI_Master_read_error_address_high_Latch register */
#define AL_ADAPTER_AXI_MSTR_RD_ERR_HI_LATCH 0x1CC
/* AXI_Master_Timeout register */
#define AL_ADAPTER_AXI_MSTR_TO 0x1D0
#define AL_ADAPTER_AXI_MSTR_TO_WR_MASK AL_FIELD_MASK(31, 16)
#define AL_ADAPTER_AXI_MSTR_TO_WR_SHIFT 16
#define AL_ADAPTER_AXI_MSTR_TO_RD_MASK AL_FIELD_MASK(15, 0)
#define AL_ADAPTER_AXI_MSTR_TO_RD_SHIFT 0
/*
* Generic control registers
*/
/* Control 0 */
#define AL_ADAPTER_GENERIC_CONTROL_0 0x1E0
/* Control 2 */
#define AL_ADAPTER_GENERIC_CONTROL_2 0x1E8
/* Control 3 */
#define AL_ADAPTER_GENERIC_CONTROL_3 0x1EC
/* Control 9 */
#define AL_ADAPTER_GENERIC_CONTROL_9 0x218
/* Control 10 */
#define AL_ADAPTER_GENERIC_CONTROL_10 0x21C
/* Control 11 */
#define AL_ADAPTER_GENERIC_CONTROL_11 0x220
/* Control 12 */
#define AL_ADAPTER_GENERIC_CONTROL_12 0x224
/* Control 13 */
#define AL_ADAPTER_GENERIC_CONTROL_13 0x228
/* Control 14 */
#define AL_ADAPTER_GENERIC_CONTROL_14 0x22C
/* Control 15 */
#define AL_ADAPTER_GENERIC_CONTROL_15 0x230
/* Control 16 */
#define AL_ADAPTER_GENERIC_CONTROL_16 0x234
/* Control 17 */
#define AL_ADAPTER_GENERIC_CONTROL_17 0x238
/* Control 18 */
#define AL_ADAPTER_GENERIC_CONTROL_18 0x23C
/* Control 19 */
#define AL_ADAPTER_GENERIC_CONTROL_19 0x240
/* Enable clock gating */
#define AL_ADAPTER_GENERIC_CONTROL_0_CLK_GATE_EN 0x01
/* When set, all transactions through the PCI conf & mem BARs get timeout */
#define AL_ADAPTER_GENERIC_CONTROL_0_ADAPTER_DIS 0x40
#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC AL_BIT(18)
#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR AL_BIT(26)
/*
* SATA registers only
*/
/* Select 125MHz free running clock from IOFAB main PLL as SATA OOB clock
* instead of using power management ref clock
*/
#define AL_ADAPTER_GENERIC_CONTROL_10_SATA_OOB_CLK_SEL AL_BIT(26)
/* AXUSER selection and value per bit (1 = address, 0 = register) */
/* Rx */
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_MASK AL_FIELD_MASK(15, 0)
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_SHIFT 0
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_MASK AL_FIELD_MASK(31, 16)
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_SHIFT 16
/* Tx */
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_MASK AL_FIELD_MASK(15, 0)
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16)
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16
/* Central VMID enabler. If set, then each entry will be used as programmed */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0)
/* Allow access to store VMID values per entry */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1)
/* VMID Address select */
/* Tx */
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8)
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8
/* Rx */
#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_MASK AL_FIELD_MASK(21, 16)
#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_SHIFT 16
/* Address Value */
/* Rx */
#define AL_ADPTR_GEN_CTL_15_SATA_VM_AWDDR_HI AL_FIELD_MASK(31, 0)
/* Tx */
#define AL_ADPTR_GEN_CTL_16_SATA_VM_ARDDR_HI AL_FIELD_MASK(31, 0)
/*
* ROB registers
*/
/* Read ROB_Enable, when disabled the read ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0)
/* Read force in-order of every read transaction */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1)
/* Read software reset */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15)
/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16)
/* Write force in-order of every write transaction */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17)
/* Write software reset */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_SW_RESET AL_BIT(31)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,59 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#include "al_serdes.h"
#include "al_hal_serdes_hssp.h"
#include "al_hal_serdes_25g.h"
static int(*handle_init[AL_SRDS_NUM_GROUPS])(void __iomem *, struct al_serdes_grp_obj *) = {
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
al_serdes_hssp_handle_init,
#if CHECK_ALPINE_V2
al_serdes_25g_handle_init,
#endif
};
int al_serdes_handle_grp_init(
void __iomem *serdes_regs_base,
enum al_serdes_group grp,
struct al_serdes_grp_obj *obj)
{
handle_init[grp](serdes_regs_base, obj);
return 0;
}

View File

@ -0,0 +1,78 @@
/*******************************************************************************
Copyright (C) 2013 Annapurna Labs Ltd.
This file is licensed under the terms of the Annapurna Labs' Commercial License
Agreement distributed with the file or available on the software download site.
Recipient shall use the content of this file only on semiconductor devices or
systems developed by or for Annapurna Labs.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_serdes_init SerDes Initialization
* @ingroup group_serdes SerDes
* @{
*
* @file al_serdes.h
*
*/
#ifndef __AL_SERDES_H__
#define __AL_SERDES_H__
#include "al_hal_serdes_interface.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#ifdef AL_DEV_ID
#define CHECK_ALPINE_V1 (AL_DEV_ID == AL_DEV_ID_ALPINE_V1)
#define CHECK_ALPINE_V2 (AL_DEV_ID == AL_DEV_ID_ALPINE_V2)
#else
#define CHECK_ALPINE_V1 1
#define CHECK_ALPINE_V2 1
#endif
enum al_serdes_group {
AL_SRDS_GRP_A = 0,
AL_SRDS_GRP_B,
AL_SRDS_GRP_C,
AL_SRDS_GRP_D,
AL_SRDS_NUM_HSSP_GROUPS,
#if CHECK_ALPINE_V2
AL_SRDS_GRP_E = AL_SRDS_NUM_HSSP_GROUPS,
AL_SRDS_NUM_GROUPS,
#else
AL_SRDS_NUM_GROUPS = AL_SRDS_NUM_HSSP_GROUPS,
#endif
};
int al_serdes_handle_grp_init(
void __iomem *serdes_regs_base,
enum al_serdes_group grp,
struct al_serdes_grp_obj *obj);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif
/** @} end of SERDES group */

View File

@ -0,0 +1,264 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @{
* @file al_hal_an_lt_wrapper_regs.h
*
* @brief ... registers
*
*/
#ifndef __AL_HAL_AN_LT_wrapper_REGS_H__
#define __AL_HAL_AN_LT_wrapper_REGS_H__
#include "al_hal_plat_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct al_an_lt_wrapper_gen {
/* [0x0] AN LT wrapper Version */
uint32_t version;
/* [0x4] AN LT general configuration */
uint32_t cfg;
uint32_t rsrvd[14];
};
struct al_an_lt_wrapper_an_lt {
/* [0x0] AN LT register file address */
uint32_t addr;
/* [0x4] PCS register file data */
uint32_t data;
/* [0x8] AN LT control signals */
uint32_t ctrl;
/* [0xc] AN LT status signals */
uint32_t status;
uint32_t rsrvd[4];
};
enum al_eth_an_lt_unit {
AL_ETH_AN_LT_UNIT_32_BIT = 0,
AL_ETH_AN_LT_UNIT_20_BIT = 1,
AL_ETH_AN_LT_UNIT_16_BIT = 2,
};
struct al_an_lt_wrapper_regs {
uint32_t rsrvd_0[64];
struct al_an_lt_wrapper_gen gen; /* [0x100] */
struct al_an_lt_wrapper_an_lt an_lt[3]; /* [0x140] */
};
/*
* Registers Fields
*/
/**** version register ****/
/* Revision number (Minor) */
#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF
#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MINOR_SHIFT 0
/* Revision number (Major) */
#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00
#define AN_LT_WRAPPER_GEN_VERSION_RELEASE_NUM_MAJOR_SHIFT 8
/* Date of release */
#define AN_LT_WRAPPER_GEN_VERSION_DATE_DAY_MASK 0x001F0000
#define AN_LT_WRAPPER_GEN_VERSION_DATE_DAY_SHIFT 16
/* Month of release */
#define AN_LT_WRAPPER_GEN_VERSION_DATA_MONTH_MASK 0x01E00000
#define AN_LT_WRAPPER_GEN_VERSION_DATA_MONTH_SHIFT 21
/* Year of release (starting from 2000) */
#define AN_LT_WRAPPER_GEN_VERSION_DATE_YEAR_MASK 0x3E000000
#define AN_LT_WRAPPER_GEN_VERSION_DATE_YEAR_SHIFT 25
/* Reserved */
#define AN_LT_WRAPPER_GEN_VERSION_RESERVED_MASK 0xC0000000
#define AN_LT_WRAPPER_GEN_VERSION_RESERVED_SHIFT 30
/**** cfg register ****/
/*
* selection between different bus widths:
* 0 16
* 1 20
* 2 32
* 3 N/A
*/
#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_MASK 0x00000003
#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_RX_SHIFT 0
/*
* selection between different bus widths:
* 0 16
* 1 20
* 2 32
* 3 N/A
*/
#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_MASK 0x0000000C
#define AN_LT_WRAPPER_GEN_CFG_AN_LT_SEL_TX_SHIFT 2
/* bypass the AN/LT block */
#define AN_LT_WRAPPER_GEN_CFG_BYPASS_RX (1 << 4)
/* bypass the AN/LT block */
#define AN_LT_WRAPPER_GEN_CFG_BYPASS_TX (1 << 5)
/**** addr register ****/
/* Address value */
#define AN_LT_WRAPPER_AN_LT_ADDR_VAL_MASK 0x000007FF
#define AN_LT_WRAPPER_AN_LT_ADDR_VAL_SHIFT 0
/**** data register ****/
/* Data value */
#define AN_LT_WRAPPER_AN_LT_DATA_VAL_MASK 0x0000FFFF
#define AN_LT_WRAPPER_AN_LT_DATA_VAL_SHIFT 0
/**** ctrl register ****/
/*
* Default Auto-Negotiation Enable. If 1, the auto-negotiation process will
* start after reset de-assertion. The application can also start the
* auto-negotiation process by writing the KXAN_CONTROL.an_enable bit with 1.
* Important: This signal is OR'ed with the KXAN_CONTROL.an_enable bit. Hence,
* when asserted (1) the application is unable to disable autonegotiation and
* writing the an_enable bit has no effect.
* Note: Even if enabled by this pin, the application must write the correct
* abilities in the KXAN_ABILITY_1/2/3 registers within 60ms from reset
* deassertion (break_link_timer).
*/
#define AN_LT_WRAPPER_AN_LT_CTRL_AN_ENA (1 << 0)
/*
* If set to 1, the Arbitration State Machine reached the TRANSMIT_DISABLE
* state.
*/
#define AN_LT_WRAPPER_AN_LT_CTRL_AN_DIS_TIMER (1 << 1)
#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS_KX (1 << 4)
#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS_KX4 (1 << 5)
#define AN_LT_WRAPPER_AN_LT_CTRL_LINK_STATUS (1 << 6)
/*
* PHY LOS indication selection
* 0 - Select input from the SerDes
* 1 - Select register value from phy_los_in_def
*/
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_SEL (1 << 8)
/* PHY LOS default value */
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_DEF (1 << 9)
/* PHY LOS polarity */
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_IN_POL (1 << 10)
/*
* PHY LOS indication selection
* 0 select AN output
* 1 - Select register value from phy_los_out_def
* 2 - Select input from the SerDes
* 3 0
*/
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_SEL_MASK 0x00003000
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_SEL_SHIFT 12
/* PHY LOS default value */
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_DEF (1 << 14)
/* PHY LOS polarity */
#define AN_LT_WRAPPER_AN_LT_CTRL_PHY_LOS_OUT_POL (1 << 15)
/**** status register ****/
/* Auto-Negotiation Done. If 1, the auto-negotiation process has completed. */
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_DONE (1 << 0)
/*
* If set to 1, auto-negotiation is enabled on the link. It represents the
* enable control bit KXAN_CONTROL.an_enable. When set to 1, the signals
* an_status/an_select are valid.
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_VAL (1 << 1)
/*
* If set to 0, auto-negotiation is in progress, if set to 1, the Arbitration
* State Machine reached the AN_GOOD_CHECK state (i.e. before autonegotiation is
* done, but the link no longer is used to transfer DME pages). Stays asserted
* also during AN_GOOD (autoneg done).
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_STATUS (1 << 2)
/*
* Selected Technology. Becomes valid when an_status is 1.
* The selection mode number (from 0 to 24) corresponds to the Technology
* Ability (A0-A24) from the ability pages (see 4.3.2.3 page 13). The mode
* selection is based on the matching technology abilities and priority.
* A value of 31 is an invalid setting that indicates that no common technology
* could be resolved. The application should then inspect the base page results
* to determine if the link is operable or not.
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_SELECT_MASK 0x000001F0
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_SELECT_SHIFT 4
/*
* If set to 1, the Arbitration State Machine reached the TRANSMIT_DISABLE state
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_AN_TR_DIS_STATUS (1 << 16)
/*
* FEC Enable. Asserts when autonegotiation base page exchange identified both
* link partners advertising FEC capability and at least one is requesting FEC.
* The signal stays constant following base page exchange until autonegotiation
* is disabled or restarted.
* Note: the information can also be extracted from the base page exchange or
* the BP_ETH_STATUS register.
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_FEC_ENA (1 << 17)
/*
* Link Training Frame Lock. If set to 1 the training frame delineation has been
* acquired.
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_LT_LOCK (1 << 20)
/*
* If set to 0, link-training is in progress, if set to 1, the training is
* completed and the PCS datapath has been enabled (phy_los_out no longer
* gated).
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_LT_STATUS (1 << 21)
/*
* If set to 1, link-training is enabled on the link. It represents the enable
* control bit PMD Control.taining enable. When set to 1, the signal lt_status
* is valid
*/
#define AN_LT_WRAPPER_AN_LT_STATUS_LT_VAL (1 << 22)
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_AN_LT_wrapper_REGS_H__ */
/** @} end of ... group */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
/*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_eth_alu_api API
* Ethernet Controller generic ALU API
* @ingroup group_eth
* @{
* @file al_hal_eth_alu.h
*
* @brief Header file for control parameters for the generic ALU unit in the Ethernet Datapath for Advanced Ethernet port.
*
*/
#ifndef __AL_HAL_ETH_ALU_H__
#define __AL_HAL_ETH_ALU_H__
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
enum AL_ETH_ALU_OPCODE
{
AL_ALU_FWD_A = 0,
AL_ALU_ARITHMETIC_ADD = 1,
AL_ALU_ARITHMETIC_SUBTRACT = 2,
AL_ALU_BITWISE_AND = 3,
AL_ALU_BITWISE_OR = 4,
AL_ALU_SHIFT_RIGHT_A_BY_B = 5,
AL_ALU_SHIFT_LEFT_A_BY_B = 6,
AL_ALU_BITWISE_XOR = 7,
AL_ALU_FWD_INV_A = 16,
AL_ALU_ARITHMETIC_ADD_INV_A_AND_B = 17,
AL_ALU_ARITHMETIC_SUBTRACT_INV_A_AND_B = 18,
AL_ALU_BITWISE_AND_INV_A_AND_B = 19,
AL_ALU_BITWISE_OR_INV_A_AND_B = 20,
AL_ALU_SHIFT_RIGHT_INV_A_BY_B = 21,
AL_ALU_SHIFT_LEFT_INV_A_BY_B = 22,
AL_ALU_BITWISE_XOR_INV_A_AND_B = 23,
AL_ALU_ARITHMETIC_ADD_A_AND_INV_B = 33,
AL_ALU_ARITHMETIC_SUBTRACT_A_AND_INV_B = 34,
AL_ALU_BITWISE_AND_A_AND_INV_B = 35,
AL_ALU_BITWISE_OR_A_AND_INV_B = 36,
AL_ALU_SHIFT_RIGHT_A_BY_INV_B = 37,
AL_ALU_SHIFT_LEFT_A_BY_INV_B = 38,
AL_ALU_BITWISE_XOR_A_AND_INV_B = 39,
AL_ALU_ARITHMETIC_ADD_INV_A_AND_INV_B = 49,
AL_ALU_ARITHMETIC_SUBTRACT_INV_A_AND = 50,
AL_ALU_BITWISE_AND_INV_A_AND_INV_B = 51,
AL_ALU_BITWISE_OR_INV_A_AND_INV_B = 52,
AL_ALU_SHIFT_RIGHT_INV_A_BY_INV_B = 53,
AL_ALU_SHIFT_LEFT_INV_A_BY_INV_B = 54,
AL_ALU_BITWISE_XOR_INV_A_AND_INV_B = 55
};
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __AL_HAL_ETH_ALU_H__ */
/** @} end of Ethernet group */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,372 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_eth_kr_api API
* Ethernet KR auto-neg and link-training driver API
* @ingroup group_eth
* @{
* @file al_hal_eth_kr.h
*
* @brief Header file for KR driver
*
*
*/
#ifndef __AL_HAL_ETH_KR_H__
#define __AL_HAL_ETH_KR_H__
#include "al_hal_eth.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* AN (Auto-negotiation) Advertisement Registers */
struct al_eth_an_adv {
/* constant value defining 802.3ap support.
* The suggested value is 0x01.*/
uint8_t selector_field;
/* Contains arbitrary data. */
uint8_t echoed_nonce;
/* pause capability. */
uint8_t capability;
/* Set to 1 to indicate a Remote Fault condition.
* Set to 0 to indicate normal operation.*/
uint8_t remote_fault;
/* Should always be set to 0. */
uint8_t acknowledge;
/* Set to 1 to indicate that the device has next pages to send.
* Set to 0 to indicate that that device has no next pages to send. */
uint8_t next_page;
/* Must be set to an arbitrary value.
* Two devices must have a different nonce for autonegotiation to
* operate (a loopback will not allow autonegotiation to complete). */
uint8_t transmitted_nonce;
uint32_t technology;
#define AL_ETH_AN_TECH_1000BASE_KX AL_BIT(0)
#define AL_ETH_AN_TECH_10GBASE_KX4 AL_BIT(1)
#define AL_ETH_AN_TECH_10GBASE_KR AL_BIT(2)
#define AL_ETH_AN_TECH_40GBASE_KR4 AL_BIT(3)
#define AL_ETH_AN_TECH_40GBASE_CR4 AL_BIT(4)
#define AL_ETH_AN_TECH_100GBASE_CR AL_BIT(5)
uint8_t fec_capability;
};
/* AN next page fields */
struct al_eth_an_np {
/* These bits can be used as message code field or unformatted code field.
* When msg_page is true, these bits represent message code field.
* Predefined message code field Code Field should be used as specified in the standard
* 802.3ap.
* For the null message code the value is 0x01.
*/
uint16_t unformatted_code_field;
/* Flag to keep track of the state of the local device's Toggle bit.
* Initial value is taken from base page. Set to 0.
*/
al_bool toggle;
/* Acknowledge 2 is used to indicate that the receiver is able to act on the information
* (or perform the task) defined in the message.
*/
al_bool ack2;
al_bool msg_page;
/* If the device does not have any more Next Pages to send, set to AL_FALSE */
al_bool next_page;
uint16_t unformatted_code_field1;
uint16_t unformatted_code_field2;
};
enum al_eth_kr_cl72_cstate {
C72_CSTATE_NOT_UPDATED = 0,
C72_CSTATE_UPDATED = 1,
C72_CSTATE_MIN = 2,
C72_CSTATE_MAX = 3,
};
enum al_eth_kr_cl72_coef_op {
AL_PHY_KR_COEF_UP_HOLD = 0,
AL_PHY_KR_COEF_UP_INC = 1,
AL_PHY_KR_COEF_UP_DEC = 2,
AL_PHY_KR_COEF_UP_RESERVED = 3
};
struct al_eth_kr_coef_up_data {
enum al_eth_kr_cl72_coef_op c_zero;
enum al_eth_kr_cl72_coef_op c_plus;
enum al_eth_kr_cl72_coef_op c_minus;
al_bool preset;
al_bool initialize;
};
struct al_eth_kr_status_report_data {
enum al_eth_kr_cl72_cstate c_zero;
enum al_eth_kr_cl72_cstate c_plus;
enum al_eth_kr_cl72_cstate c_minus;
al_bool receiver_ready;
};
enum al_eth_an_lt_lane {
AL_ETH_AN__LT_LANE_0,
AL_ETH_AN__LT_LANE_1,
AL_ETH_AN__LT_LANE_2,
AL_ETH_AN__LT_LANE_3,
};
/**
* get the last received coefficient update message from the link partner
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param lpcoeff coeff update received
*
*/
void al_eth_lp_coeff_up_get(
struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
struct al_eth_kr_coef_up_data *lpcoeff);
/**
* get the last received status report message from the link partner
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param status status report received
*
*/
void al_eth_lp_status_report_get(
struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
struct al_eth_kr_status_report_data *status);
/**
* set the coefficient data for the next message that will be sent to lp
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param ldcoeff coeff update to send
*
*/
void al_eth_ld_coeff_up_set(
struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
struct al_eth_kr_coef_up_data *ldcoeff);
/**
* set the status report message for the next message that will be sent to lp
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param status status report to send
*
*/
void al_eth_ld_status_report_set(
struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
struct al_eth_kr_status_report_data *status);
/**
* get the receiver frame lock status
*
* @param adapter pointer to the private structure
* @param lane lane number
*
* @return true if Training frame delineation is detected, otherwise false.
*/
al_bool al_eth_kr_receiver_frame_lock_get(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/**
* get the start up protocol progress status
*
* @param adapter pointer to the private structure
* @param lane lane number
*
* @return true if the startup protocol is in progress.
*/
al_bool al_eth_kr_startup_proto_prog_get(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/**
* indicate the receiver is ready (the link training is completed)
*
* @param adapter pointer to the private structure
* @param lane lane number
*
*/
void al_eth_receiver_ready_set(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/**
* read Training failure status.
*
* @param adapter pointer to the private structure
* @param lane lane number
*
*@return true if Training failure has been detected.
*/
al_bool al_eth_kr_training_status_fail_get(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/****************************** auto negotiation *******************************/
/**
* Initialize Auto-negotiation
* - Program Ability Registers (Advertisement Registers)
* - Clear Status latches
* @param adapter pointer to the private structure
* @param an_adv pointer to the AN Advertisement Registers structure
* when NULL, the registers will not be updated.
*
* @return 0 on success. otherwise on failure.
*/
int al_eth_kr_an_init(struct al_hal_eth_adapter *adapter,
struct al_eth_an_adv *an_adv);
/**
* Enable/Restart Auto-negotiation
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param lt_enable initialize link training as well
*
* @return 0 on success. otherwise on failure.
*/
int al_eth_kr_an_start(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
al_bool next_page_enable,
al_bool lt_enable);
int al_eth_kr_next_page_write(struct al_hal_eth_adapter *adapter,
struct al_eth_an_np *np);
int al_eth_kr_next_page_read(struct al_hal_eth_adapter *adapter,
struct al_eth_an_np *np);
/**
* Stop Auto-negotiation
*
* Stopping the auto-negotiation will prevent the mac from sending the last page
* to the link partner in case it start the AN again. It must be called after
* link training is completed or the software will lose sync with the HW state
* machine
*
* @param adapter pointer to the private structure
*
*/
void al_eth_kr_an_stop(struct al_hal_eth_adapter *adapter);
/**
* Check Auto-negotiation event done
*
* @param adapter pointer to the private structure
* @param page_received Set to true if the AN page received indication is set.
* Set to false otherwise.
* @param an_completed Set to true of the AN completed indication is set.
* Set to false otherwise.
* @param error Set to true if any error encountered
*
*/
void al_eth_kr_an_status_check(struct al_hal_eth_adapter *adapter,
al_bool *page_received,
al_bool *an_completed,
al_bool *error);
/**
* Read the remote auto-negotiation advertising.
* This function is safe to called after al_eth_kr_an_status_check returned
* with page_received set.
*
* @param adapter pointer to the private structure
* @param an_adv pointer to the AN Advertisement Registers structure
*
*/
void al_eth_kr_an_read_adv(struct al_hal_eth_adapter *adapter,
struct al_eth_an_adv *an_adv);
/****************************** link training **********************************/
/**
* Initialize Link-training.
* Clear the status register and set the local coefficient update and status
* to zero.
*
* @param adapter pointer to the private structure
* @param lane lane number
*
*/
void al_eth_kr_lt_initialize(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/**
* Wait for frame lock.
*
* @param adapter pointer to the private structure
* @param lane lane number
* @param timeout timeout in usec.
*
* @return true if frame lock received. false otherwise.
*/
al_bool al_eth_kr_lt_frame_lock_wait(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane,
uint32_t timeout);
/**
* reset the 10GBase- KR startup protocol and begin its operation
*
* @param adapter pointer to the private structure
* @param lane lane number
*
*/
void al_eth_kr_lt_restart(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
/**
* reset the 10GBase- KR startup protocol and end its operation
*
* @param adapter pointer to the private structure
* @param lane lane number
*
*/
void al_eth_kr_lt_stop(struct al_hal_eth_adapter *adapter,
enum al_eth_an_lt_lane lane);
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /*__AL_HAL_ETH_KR_H__*/
/** @} end of Ethernet kr group */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff