diff options
Diffstat (limited to 'include/soc')
55 files changed, 3461 insertions, 999 deletions
diff --git a/include/soc/amlogic/meson_ddr_pmu.h b/include/soc/amlogic/meson_ddr_pmu.h new file mode 100644 index 000000000000..4a33e4ab8ada --- /dev/null +++ b/include/soc/amlogic/meson_ddr_pmu.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Amlogic, Inc. All rights reserved. + */ + +#ifndef __MESON_DDR_PMU_H__ +#define __MESON_DDR_PMU_H__ + +#define MAX_CHANNEL_NUM 8 + +enum { + ALL_CHAN_COUNTER_ID, + CHAN1_COUNTER_ID, + CHAN2_COUNTER_ID, + CHAN3_COUNTER_ID, + CHAN4_COUNTER_ID, + CHAN5_COUNTER_ID, + CHAN6_COUNTER_ID, + CHAN7_COUNTER_ID, + CHAN8_COUNTER_ID, + COUNTER_MAX_ID, +}; + +struct dmc_info; + +struct dmc_counter { + u64 all_cnt; /* The count of all requests come in/out ddr controller */ + union { + u64 all_req; + struct { + u64 all_idle_cnt; + u64 all_16bit_cnt; + }; + }; + u64 channel_cnt[MAX_CHANNEL_NUM]; /* To save a DMC bandwidth-monitor channel counter */ +}; + +struct dmc_hw_info { + void (*enable)(struct dmc_info *info); + void (*disable)(struct dmc_info *info); + /* Bind an axi line to a bandwidth-monitor channel */ + void (*set_axi_filter)(struct dmc_info *info, int axi_id, int chann); + int (*irq_handler)(struct dmc_info *info, + struct dmc_counter *counter); + void (*get_counters)(struct dmc_info *info, + struct dmc_counter *counter); + + int dmc_nr; /* The number of dmc controller */ + int chann_nr; /* The number of dmc bandwidth monitor channels */ + struct attribute **fmt_attr; + const u64 capability[2]; +}; + +struct dmc_info { + const struct dmc_hw_info *hw_info; + + void __iomem *ddr_reg[4]; + unsigned long timer_value; /* Timer value in TIMER register */ + void __iomem *pll_reg; + int irq_num; /* irq vector number */ +}; + +int meson_ddr_pmu_create(struct platform_device *pdev); +int meson_ddr_pmu_remove(struct platform_device *pdev); + +#endif /* __MESON_DDR_PMU_H__ */ diff --git a/include/soc/arc/timers.h b/include/soc/arc/timers.h index 7ecde3b159c8..ae99d3e855f1 100644 --- a/include/soc/arc/timers.h +++ b/include/soc/arc/timers.h @@ -17,8 +17,8 @@ #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ /* CTRL reg bits */ -#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ -#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ +#define ARC_TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ +#define ARC_TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ #define ARC_TIMERN_MAX 0xFFFFFFFF diff --git a/include/soc/at91/atmel_tcb.h b/include/soc/at91/atmel_tcb.h index 1d7071dc0bca..26b56a07bd1f 100644 --- a/include/soc/at91/atmel_tcb.h +++ b/include/soc/at91/atmel_tcb.h @@ -77,9 +77,6 @@ struct atmel_tc { bool allocated; }; -extern struct atmel_tc *atmel_tc_alloc(unsigned block); -extern void atmel_tc_free(struct atmel_tc *tc); - /* platform-specific ATMEL_TC_TIMER_CLOCKx divisors (0 means 32KiHz) */ extern const u8 atmel_tc_divisors[5]; diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h new file mode 100644 index 000000000000..5ad7ac2e3a7c --- /dev/null +++ b/include/soc/at91/sama7-ddr.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Microchip SAMA7 UDDR Controller and DDR3 PHY Controller registers offsets + * and bit definitions. + * + * Copyright (C) [2020] Microchip Technology Inc. and its subsidiaries + * + * Author: Claudu Beznea <claudiu.beznea@microchip.com> + */ + +#ifndef __SAMA7_DDR_H__ +#define __SAMA7_DDR_H__ + +/* DDR3PHY */ +#define DDR3PHY_PIR (0x04) /* DDR3PHY PHY Initialization Register */ +#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */ +#define DDR3PHY_PIR_ITMSRST (1 << 4) /* Interface Timing Module Soft Reset */ +#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */ +#define DDR3PHY_PIR_DLLSRST (1 << 1) /* DLL Soft Rest */ +#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */ + +#define DDR3PHY_PGCR (0x08) /* DDR3PHY PHY General Configuration Register */ +#define DDR3PHY_PGCR_CKDV1 (1 << 13) /* CK# Disable Value */ +#define DDR3PHY_PGCR_CKDV0 (1 << 12) /* CK Disable Value */ + +#define DDR3PHY_PGSR (0x0C) /* DDR3PHY PHY General Status Register */ +#define DDR3PHY_PGSR_IDONE (1 << 0) /* Initialization Done */ + +#define DDR3PHY_ACDLLCR (0x14) /* DDR3PHY AC DLL Control Register */ +#define DDR3PHY_ACDLLCR_DLLSRST (1 << 30) /* DLL Soft Reset */ + +#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */ +#define DDR3PHY_ACIOCR_CSPDD_CS0 (1 << 18) /* CS#[0] Power Down Driver */ +#define DDR3PHY_ACIOCR_CKPDD_CK0 (1 << 8) /* CK[0] Power Down Driver */ +#define DDR3PHY_ACIORC_ACPDD (1 << 3) /* AC Power Down Driver */ + +#define DDR3PHY_DXCCR (0x28) /* DDR3PHY DATX8 Common Configuration Register */ +#define DDR3PHY_DXCCR_DXPDR (1 << 3) /* Data Power Down Receiver */ + +#define DDR3PHY_DSGCR (0x2C) /* DDR3PHY DDR System General Configuration Register */ +#define DDR3PHY_DSGCR_ODTPDD_ODT0 (1 << 20) /* ODT[0] Power Down Driver */ + +#define DDR3PHY_ZQ0SR0 (0x188) /* ZQ status register 0 */ +#define DDR3PHY_ZQ0SR0_PDO_OFF (0) /* Pull-down output impedance select offset */ +#define DDR3PHY_ZQ0SR0_PUO_OFF (5) /* Pull-up output impedance select offset */ +#define DDR3PHY_ZQ0SR0_PDODT_OFF (10) /* Pull-down on-die termination impedance select offset */ +#define DDR3PHY_ZQ0SRO_PUODT_OFF (15) /* Pull-up on-die termination impedance select offset */ + +#define DDR3PHY_DX0DLLCR (0x1CC) /* DDR3PHY DATX8 DLL Control Register */ +#define DDR3PHY_DX1DLLCR (0x20C) /* DDR3PHY DATX8 DLL Control Register */ +#define DDR3PHY_DXDLLCR_DLLDIS (1 << 31) /* DLL Disable */ + +/* UDDRC */ +#define UDDRC_STAT (0x04) /* UDDRC Operating Mode Status Register */ +#define UDDRC_STAT_SELFREF_TYPE_DIS (0x0 << 4) /* SDRAM is not in Self-refresh */ +#define UDDRC_STAT_SELFREF_TYPE_PHY (0x1 << 4) /* SDRAM is in Self-refresh, which was caused by PHY Master Request */ +#define UDDRC_STAT_SELFREF_TYPE_SW (0x2 << 4) /* SDRAM is in Self-refresh, which was not caused solely under Automatic Self-refresh control */ +#define UDDRC_STAT_SELFREF_TYPE_AUTO (0x3 << 4) /* SDRAM is in Self-refresh, which was caused by Automatic Self-refresh only */ +#define UDDRC_STAT_SELFREF_TYPE_MSK (0x3 << 4) /* Self-refresh type mask */ +#define UDDRC_STAT_OPMODE_INIT (0x0 << 0) /* Init */ +#define UDDRC_STAT_OPMODE_NORMAL (0x1 << 0) /* Normal */ +#define UDDRC_STAT_OPMODE_PWRDOWN (0x2 << 0) /* Power-down */ +#define UDDRC_STAT_OPMODE_SELF_REFRESH (0x3 << 0) /* Self-refresh */ +#define UDDRC_STAT_OPMODE_MSK (0x7 << 0) /* Operating mode mask */ + +#define UDDRC_PWRCTL (0x30) /* UDDRC Low Power Control Register */ +#define UDDRC_PWRCTL_SELFREF_EN (1 << 0) /* Automatic self-refresh */ +#define UDDRC_PWRCTL_SELFREF_SW (1 << 5) /* Software self-refresh */ + +#define UDDRC_DFIMISC (0x1B0) /* UDDRC DFI Miscellaneous Control Register */ +#define UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN (1 << 0) /* PHY initialization complete enable signal */ + +#define UDDRC_SWCTRL (0x320) /* UDDRC Software Register Programming Control Enable */ +#define UDDRC_SWCTRL_SW_DONE (1 << 0) /* Enable quasi-dynamic register programming outside reset */ + +#define UDDRC_SWSTAT (0x324) /* UDDRC Software Register Programming Control Status */ +#define UDDRC_SWSTAT_SW_DONE_ACK (1 << 0) /* Register programming done */ + +#define UDDRC_PSTAT (0x3FC) /* UDDRC Port Status Register */ +#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */ + +#define UDDRC_PCTRL_0 (0x490) /* UDDRC Port 0 Control Register */ +#define UDDRC_PCTRL_1 (0x540) /* UDDRC Port 1 Control Register */ +#define UDDRC_PCTRL_2 (0x5F0) /* UDDRC Port 2 Control Register */ +#define UDDRC_PCTRL_3 (0x6A0) /* UDDRC Port 3 Control Register */ +#define UDDRC_PCTRL_4 (0x750) /* UDDRC Port 4 Control Register */ + +#endif /* __SAMA7_DDR_H__ */ diff --git a/include/soc/at91/sama7-sfrbu.h b/include/soc/at91/sama7-sfrbu.h new file mode 100644 index 000000000000..76b740810d34 --- /dev/null +++ b/include/soc/at91/sama7-sfrbu.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Microchip SAMA7 SFRBU registers offsets and bit definitions. + * + * Copyright (C) [2020] Microchip Technology Inc. and its subsidiaries + * + * Author: Claudu Beznea <claudiu.beznea@microchip.com> + */ + +#ifndef __SAMA7_SFRBU_H__ +#define __SAMA7_SFRBU_H__ + +#ifdef CONFIG_SOC_SAMA7 + +#define AT91_SFRBU_PSWBU (0x00) /* SFRBU Power Switch BU Control Register */ +#define AT91_SFRBU_PSWBU_PSWKEY (0x4BD20C << 8) /* Specific value mandatory to allow writing of other register bits */ +#define AT91_SFRBU_PSWBU_STATE (1 << 2) /* Power switch BU state */ +#define AT91_SFRBU_PSWBU_SOFTSWITCH (1 << 1) /* Power switch BU source selection */ +#define AT91_SFRBU_PSWBU_CTRL (1 << 0) /* Power switch BU control */ + +#define AT91_SFRBU_25LDOCR (0x0C) /* SFRBU 2.5V LDO Control Register */ +#define AT91_SFRBU_25LDOCR_LDOANAKEY (0x3B6E18 << 8) /* Specific value mandatory to allow writing of other register bits. */ +#define AT91_SFRBU_25LDOCR_STATE (1 << 3) /* LDOANA Switch On/Off Control */ +#define AT91_SFRBU_25LDOCR_LP (1 << 2) /* LDOANA Low-Power Mode Control */ +#define AT91_SFRBU_PD_VALUE_MSK (0x3) +#define AT91_SFRBU_25LDOCR_PD_VALUE(v) ((v) & AT91_SFRBU_PD_VALUE_MSK) /* LDOANA Pull-down value */ + +#define AT91_FRBU_DDRPWR (0x10) /* SFRBU DDR Power Control Register */ +#define AT91_FRBU_DDRPWR_STATE (1 << 0) /* DDR Power Mode State */ + +#endif /* CONFIG_SOC_SAMA7 */ + +#endif /* __SAMA7_SFRBU_H__ */ + diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index cc9cdbc66403..73cac8d0287e 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -91,6 +91,7 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049, RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050, RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058, + RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066, /* Dispmanx TAGS */ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, @@ -135,12 +136,55 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, }; +enum rpi_firmware_clk_id { + RPI_FIRMWARE_EMMC_CLK_ID = 1, + RPI_FIRMWARE_UART_CLK_ID, + RPI_FIRMWARE_ARM_CLK_ID, + RPI_FIRMWARE_CORE_CLK_ID, + RPI_FIRMWARE_V3D_CLK_ID, + RPI_FIRMWARE_H264_CLK_ID, + RPI_FIRMWARE_ISP_CLK_ID, + RPI_FIRMWARE_SDRAM_CLK_ID, + RPI_FIRMWARE_PIXEL_CLK_ID, + RPI_FIRMWARE_PWM_CLK_ID, + RPI_FIRMWARE_HEVC_CLK_ID, + RPI_FIRMWARE_EMMC2_CLK_ID, + RPI_FIRMWARE_M2MC_CLK_ID, + RPI_FIRMWARE_PIXEL_BVB_CLK_ID, + RPI_FIRMWARE_VEC_CLK_ID, + RPI_FIRMWARE_NUM_CLK_ID, +}; + +/** + * struct rpi_firmware_clk_rate_request - Firmware Request for a rate + * @id: ID of the clock being queried + * @rate: Rate in Hertz. Set by the firmware. + * + * Used by @RPI_FIRMWARE_GET_CLOCK_RATE, @RPI_FIRMWARE_GET_CLOCK_MEASURED, + * @RPI_FIRMWARE_GET_MAX_CLOCK_RATE and @RPI_FIRMWARE_GET_MIN_CLOCK_RATE. + */ +struct rpi_firmware_clk_rate_request { + __le32 id; + __le32 rate; +} __packed; + +#define RPI_FIRMWARE_CLK_RATE_REQUEST(_id) \ + { \ + .id = cpu_to_le32(_id), \ + } + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len); int rpi_firmware_property_list(struct rpi_firmware *fw, void *data, size_t tag_size); +void rpi_firmware_put(struct rpi_firmware *fw); +unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, + unsigned int id); +struct device_node *rpi_firmware_find_node(void); struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node); #else static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len) @@ -154,10 +198,29 @@ static inline int rpi_firmware_property_list(struct rpi_firmware *fw, return -ENOSYS; } +static inline void rpi_firmware_put(struct rpi_firmware *fw) { } + +static inline unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, + unsigned int id) +{ + return UINT_MAX; +} + +static inline struct device_node *rpi_firmware_find_node(void) +{ + return NULL; +} + static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) { return NULL; } + +static inline struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node) +{ + return NULL; +} #endif #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */ diff --git a/include/soc/brcmstb/common.h b/include/soc/brcmstb/common.h deleted file mode 100644 index e4fe76856de9..000000000000 --- a/include/soc/brcmstb/common.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright © 2014 NVIDIA Corporation - * Copyright © 2015 Broadcom Corporation - */ - -#ifndef __SOC_BRCMSTB_COMMON_H__ -#define __SOC_BRCMSTB_COMMON_H__ - -bool soc_is_brcmstb(void); - -#endif /* __SOC_BRCMSTB_COMMON_H__ */ diff --git a/include/soc/canaan/k210-sysctl.h b/include/soc/canaan/k210-sysctl.h new file mode 100644 index 000000000000..0c2b2c2dabca --- /dev/null +++ b/include/soc/canaan/k210-sysctl.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com> + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef K210_SYSCTL_H +#define K210_SYSCTL_H + +/* + * Kendryte K210 SoC system controller registers offsets. + * Taken from Kendryte SDK (kendryte-standalone-sdk). + */ +#define K210_SYSCTL_GIT_ID 0x00 /* Git short commit id */ +#define K210_SYSCTL_UART_BAUD 0x04 /* Default UARTHS baud rate */ +#define K210_SYSCTL_PLL0 0x08 /* PLL0 controller */ +#define K210_SYSCTL_PLL1 0x0C /* PLL1 controller */ +#define K210_SYSCTL_PLL2 0x10 /* PLL2 controller */ +#define K210_SYSCTL_PLL_LOCK 0x18 /* PLL lock tester */ +#define K210_SYSCTL_ROM_ERROR 0x1C /* AXI ROM detector */ +#define K210_SYSCTL_SEL0 0x20 /* Clock select controller 0 */ +#define K210_SYSCTL_SEL1 0x24 /* Clock select controller 1 */ +#define K210_SYSCTL_EN_CENT 0x28 /* Central clock enable */ +#define K210_SYSCTL_EN_PERI 0x2C /* Peripheral clock enable */ +#define K210_SYSCTL_SOFT_RESET 0x30 /* Soft reset ctrl */ +#define K210_SYSCTL_PERI_RESET 0x34 /* Peripheral reset controller */ +#define K210_SYSCTL_THR0 0x38 /* Clock threshold controller 0 */ +#define K210_SYSCTL_THR1 0x3C /* Clock threshold controller 1 */ +#define K210_SYSCTL_THR2 0x40 /* Clock threshold controller 2 */ +#define K210_SYSCTL_THR3 0x44 /* Clock threshold controller 3 */ +#define K210_SYSCTL_THR4 0x48 /* Clock threshold controller 4 */ +#define K210_SYSCTL_THR5 0x4C /* Clock threshold controller 5 */ +#define K210_SYSCTL_THR6 0x50 /* Clock threshold controller 6 */ +#define K210_SYSCTL_MISC 0x54 /* Miscellaneous controller */ +#define K210_SYSCTL_PERI 0x58 /* Peripheral controller */ +#define K210_SYSCTL_SPI_SLEEP 0x5C /* SPI sleep controller */ +#define K210_SYSCTL_RESET_STAT 0x60 /* Reset source status */ +#define K210_SYSCTL_DMA_SEL0 0x64 /* DMA handshake selector 0 */ +#define K210_SYSCTL_DMA_SEL1 0x68 /* DMA handshake selector 1 */ +#define K210_SYSCTL_POWER_SEL 0x6C /* IO Power Mode Select controller */ + +void k210_clk_early_init(void __iomem *regs); + +#endif diff --git a/include/soc/fsl/caam-blob.h b/include/soc/fsl/caam-blob.h new file mode 100644 index 000000000000..937cac52f36d --- /dev/null +++ b/include/soc/fsl/caam-blob.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de> + */ + +#ifndef __CAAM_BLOB_GEN +#define __CAAM_BLOB_GEN + +#include <linux/types.h> +#include <linux/errno.h> + +#define CAAM_BLOB_KEYMOD_LENGTH 16 +#define CAAM_BLOB_OVERHEAD (32 + 16) +#define CAAM_BLOB_MAX_LEN 4096 + +struct caam_blob_priv; + +/** + * struct caam_blob_info - information for CAAM blobbing + * @input: pointer to input buffer (must be DMAable) + * @input_len: length of @input buffer in bytes. + * @output: pointer to output buffer (must be DMAable) + * @output_len: length of @output buffer in bytes. + * @key_mod: key modifier + * @key_mod_len: length of @key_mod in bytes. + * May not exceed %CAAM_BLOB_KEYMOD_LENGTH + */ +struct caam_blob_info { + void *input; + size_t input_len; + + void *output; + size_t output_len; + + const void *key_mod; + size_t key_mod_len; +}; + +/** + * caam_blob_gen_init - initialize blob generation + * Return: pointer to new &struct caam_blob_priv instance on success + * and ``ERR_PTR(-ENODEV)`` if CAAM has no hardware blobbing support + * or no job ring could be allocated. + */ +struct caam_blob_priv *caam_blob_gen_init(void); + +/** + * caam_blob_gen_exit - free blob generation resources + * @priv: instance returned by caam_blob_gen_init() + */ +void caam_blob_gen_exit(struct caam_blob_priv *priv); + +/** + * caam_process_blob - encapsulate or decapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing key, blob and + * key modifier buffers. + * @encap: true for encapsulation, false for decapsulation + * + * Return: %0 and sets ``info->output_len`` on success and a negative + * error code otherwise. + */ +int caam_process_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info, bool encap); + +/** + * caam_encap_blob - encapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing input key, + * output blob and key modifier buffers. + * + * Return: %0 and sets ``info->output_len`` on success and + * a negative error code otherwise. + */ +static inline int caam_encap_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info) +{ + if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD) + return -EINVAL; + + return caam_process_blob(priv, info, true); +} + +/** + * caam_decap_blob - decapsulate blob + * @priv: instance returned by caam_blob_gen_init() + * @info: pointer to blobbing info describing output key, + * input blob and key modifier buffers. + * + * Return: %0 and sets ``info->output_len`` on success and + * a negative error code otherwise. + */ +static inline int caam_decap_blob(struct caam_blob_priv *priv, + struct caam_blob_info *info) +{ + if (info->input_len < CAAM_BLOB_OVERHEAD || + info->output_len < info->input_len - CAAM_BLOB_OVERHEAD) + return -EINVAL; + + return caam_process_blob(priv, info, false); +} + +#endif diff --git a/include/soc/fsl/dpaa2-fd.h b/include/soc/fsl/dpaa2-fd.h index 90ae8d191f1a..bae490cac0aa 100644 --- a/include/soc/fsl/dpaa2-fd.h +++ b/include/soc/fsl/dpaa2-fd.h @@ -7,7 +7,8 @@ #ifndef __FSL_DPAA2_FD_H #define __FSL_DPAA2_FD_H -#include <linux/kernel.h> +#include <linux/byteorder/generic.h> +#include <linux/types.h> /** * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2 diff --git a/include/soc/fsl/dpaa2-io.h b/include/soc/fsl/dpaa2-io.h index c9d849924f89..4bf62de2e00e 100644 --- a/include/soc/fsl/dpaa2-io.h +++ b/include/soc/fsl/dpaa2-io.h @@ -44,6 +44,7 @@ struct device; * @regs_cinh: The cache inhibited regs * @dpio_id: The dpio index * @qman_version: The qman version + * @qman_clk: The qman clock frequency in Hz * * Describes the attributes and features of the DPIO object. */ @@ -55,6 +56,7 @@ struct dpaa2_io_desc { void __iomem *regs_cinh; int dpio_id; u32 qman_version; + u32 qman_clk; }; struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc, @@ -129,4 +131,11 @@ int dpaa2_io_query_fq_count(struct dpaa2_io *d, u32 fqid, u32 *fcnt, u32 *bcnt); int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid, u32 *num); + +int dpaa2_io_set_irq_coalescing(struct dpaa2_io *d, u32 irq_holdoff); +void dpaa2_io_get_irq_coalescing(struct dpaa2_io *d, u32 *irq_holdoff); +void dpaa2_io_set_adaptive_coalescing(struct dpaa2_io *d, + int use_adaptive_rx_coalesce); +int dpaa2_io_get_adaptive_coalescing(struct dpaa2_io *d); +void dpaa2_io_update_net_dim(struct dpaa2_io *d, __u64 frames, __u64 bytes); #endif /* __FSL_DPAA2_IO_H */ diff --git a/include/soc/fsl/qe/immap_qe.h b/include/soc/fsl/qe/immap_qe.h index 7614fee532f1..edd601f53f5d 100644 --- a/include/soc/fsl/qe/immap_qe.h +++ b/include/soc/fsl/qe/immap_qe.h @@ -13,7 +13,8 @@ #define _ASM_POWERPC_IMMAP_QE_H #ifdef __KERNEL__ -#include <linux/kernel.h> +#include <linux/types.h> + #include <asm/io.h> #define QE_IMMAP_SIZE (1024 * 1024) /* 1MB from 1MB+IMMR */ diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h index 3feddfec9f87..af793f2a0ec4 100644 --- a/include/soc/fsl/qe/qe.h +++ b/include/soc/fsl/qe/qe.h @@ -27,12 +27,6 @@ #define QE_NUM_OF_BRGS 16 #define QE_NUM_OF_PORTS 1024 -/* Memory partitions -*/ -#define MEM_PART_SYSTEM 0 -#define MEM_PART_SECONDARY 1 -#define MEM_PART_MURAM 2 - /* Clocks and BRGs */ enum qe_clock { QE_CLK_NONE = 0, @@ -102,8 +96,9 @@ s32 cpm_muram_alloc(unsigned long size, unsigned long align); void cpm_muram_free(s32 offset); s32 cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); void __iomem *cpm_muram_addr(unsigned long offset); -unsigned long cpm_muram_offset(void __iomem *addr); +unsigned long cpm_muram_offset(const void __iomem *addr); dma_addr_t cpm_muram_dma(void __iomem *addr); +void cpm_muram_free_addr(const void __iomem *addr); #else static inline s32 cpm_muram_alloc(unsigned long size, unsigned long align) @@ -126,7 +121,7 @@ static inline void __iomem *cpm_muram_addr(unsigned long offset) return NULL; } -static inline unsigned long cpm_muram_offset(void __iomem *addr) +static inline unsigned long cpm_muram_offset(const void __iomem *addr) { return -ENOSYS; } @@ -135,6 +130,9 @@ static inline dma_addr_t cpm_muram_dma(void __iomem *addr) { return 0; } +static inline void cpm_muram_free_addr(const void __iomem *addr) +{ +} #endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ /* QE PIO */ @@ -174,14 +172,15 @@ static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; } /* * Pin multiplexing functions. */ +struct device; struct qe_pin; #ifdef CONFIG_QE_GPIO -extern struct qe_pin *qe_pin_request(struct device_node *np, int index); +extern struct qe_pin *qe_pin_request(struct device *dev, int index); extern void qe_pin_free(struct qe_pin *qe_pin); extern void qe_pin_set_gpio(struct qe_pin *qe_pin); extern void qe_pin_set_dedicated(struct qe_pin *pin); #else -static inline struct qe_pin *qe_pin_request(struct device_node *np, int index) +static inline struct qe_pin *qe_pin_request(struct device *dev, int index) { return ERR_PTR(-ENOSYS); } @@ -239,42 +238,27 @@ static inline int qe_alive_during_sleep(void) #define qe_muram_addr cpm_muram_addr #define qe_muram_offset cpm_muram_offset #define qe_muram_dma cpm_muram_dma +#define qe_muram_free_addr cpm_muram_free_addr -#ifdef CONFIG_PPC32 -#define qe_iowrite8(val, addr) out_8(addr, val) -#define qe_iowrite16be(val, addr) out_be16(addr, val) -#define qe_iowrite32be(val, addr) out_be32(addr, val) -#define qe_ioread8(addr) in_8(addr) -#define qe_ioread16be(addr) in_be16(addr) -#define qe_ioread32be(addr) in_be32(addr) -#else -#define qe_iowrite8(val, addr) iowrite8(val, addr) -#define qe_iowrite16be(val, addr) iowrite16be(val, addr) -#define qe_iowrite32be(val, addr) iowrite32be(val, addr) -#define qe_ioread8(addr) ioread8(addr) -#define qe_ioread16be(addr) ioread16be(addr) -#define qe_ioread32be(addr) ioread32be(addr) -#endif - -#define qe_setbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) | (_v), (_addr)) -#define qe_clrbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) & ~(_v), (_addr)) +#define qe_setbits_be32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr)) +#define qe_clrbits_be32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr)) -#define qe_setbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) | (_v), (_addr)) -#define qe_clrbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) & ~(_v), (_addr)) +#define qe_setbits_be16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr)) +#define qe_clrbits_be16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr)) -#define qe_setbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) | (_v), (_addr)) -#define qe_clrbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) & ~(_v), (_addr)) +#define qe_setbits_8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr)) +#define qe_clrbits_8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr)) #define qe_clrsetbits_be32(addr, clear, set) \ - qe_iowrite32be((qe_ioread32be(addr) & ~(clear)) | (set), (addr)) + iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr)) #define qe_clrsetbits_be16(addr, clear, set) \ - qe_iowrite16be((qe_ioread16be(addr) & ~(clear)) | (set), (addr)) + iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr)) #define qe_clrsetbits_8(addr, clear, set) \ - qe_iowrite8((qe_ioread8(addr) & ~(clear)) | (set), (addr)) + iowrite8((ioread8(addr) & ~(clear)) | (set), (addr)) /* Structure that defines QE firmware binary files. * - * See Documentation/powerpc/qe_firmware.rst for a description of these + * See Documentation/arch/powerpc/qe_firmware.rst for a description of these * fields. */ struct qe_firmware { diff --git a/include/soc/fsl/qe/qe_tdm.h b/include/soc/fsl/qe/qe_tdm.h index b6febe225071..43ea830cfe1f 100644 --- a/include/soc/fsl/qe/qe_tdm.h +++ b/include/soc/fsl/qe/qe_tdm.h @@ -10,8 +10,8 @@ #ifndef _QE_TDM_H_ #define _QE_TDM_H_ -#include <linux/kernel.h> #include <linux/list.h> +#include <linux/types.h> #include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/qe.h> @@ -19,6 +19,8 @@ #include <soc/fsl/qe/ucc.h> #include <soc/fsl/qe/ucc_fast.h> +struct device_node; + /* SI RAM entries */ #define SIR_LAST 0x0001 #define SIR_BYTE 0x0002 diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h new file mode 100644 index 000000000000..2a333fc1ea81 --- /dev/null +++ b/include/soc/fsl/qe/qmc.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QMC management + * + * Copyright 2022 CS GROUP France + * + * Author: Herve Codina <herve.codina@bootlin.com> + */ +#ifndef __SOC_FSL_QMC_H__ +#define __SOC_FSL_QMC_H__ + +#include <linux/bits.h> +#include <linux/types.h> + +struct device_node; +struct device; +struct qmc_chan; + +struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name); +struct qmc_chan *qmc_chan_get_bychild(struct device_node *np); +void qmc_chan_put(struct qmc_chan *chan); +struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct device_node *np, + const char *phandle_name); +struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev, struct device_node *np); + +enum qmc_mode { + QMC_TRANSPARENT, + QMC_HDLC, +}; + +struct qmc_chan_info { + enum qmc_mode mode; + unsigned long rx_fs_rate; + unsigned long rx_bit_rate; + u8 nb_rx_ts; + unsigned long tx_fs_rate; + unsigned long tx_bit_rate; + u8 nb_tx_ts; +}; + +int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info); + +struct qmc_chan_ts_info { + u64 rx_ts_mask_avail; + u64 tx_ts_mask_avail; + u64 rx_ts_mask; + u64 tx_ts_mask; +}; + +int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info *ts_info); +int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct qmc_chan_ts_info *ts_info); + +struct qmc_chan_param { + enum qmc_mode mode; + union { + struct { + u16 max_rx_buf_size; + u16 max_rx_frame_size; + bool is_crc32; + } hdlc; + struct { + u16 max_rx_buf_size; + } transp; + }; +}; + +int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param); + +int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, + void (*complete)(void *context), void *context); + +/* Flags available (ORed) for read complete() flags parameter in HDLC mode. + * No flags are available in transparent mode and the read complete() flags + * parameter has no meaning in transparent mode. + */ +#define QMC_RX_FLAG_HDLC_LAST BIT(11) /* Last in frame */ +#define QMC_RX_FLAG_HDLC_FIRST BIT(10) /* First in frame */ +#define QMC_RX_FLAG_HDLC_OVF BIT(5) /* Data overflow */ +#define QMC_RX_FLAG_HDLC_UNA BIT(4) /* Unaligned (ie. bits received not multiple of 8) */ +#define QMC_RX_FLAG_HDLC_ABORT BIT(3) /* Received an abort sequence (seven consecutive ones) */ +#define QMC_RX_FLAG_HDLC_CRC BIT(2) /* CRC error */ + +int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, + void (*complete)(void *context, size_t length, + unsigned int flags), + void *context); + +#define QMC_CHAN_READ (1<<0) +#define QMC_CHAN_WRITE (1<<1) +#define QMC_CHAN_ALL (QMC_CHAN_READ | QMC_CHAN_WRITE) + +int qmc_chan_start(struct qmc_chan *chan, int direction); +int qmc_chan_stop(struct qmc_chan *chan, int direction); +int qmc_chan_reset(struct qmc_chan *chan, int direction); + +#endif /* __SOC_FSL_QMC_H__ */ diff --git a/include/soc/fsl/qe/ucc_fast.h b/include/soc/fsl/qe/ucc_fast.h index dc4e79468094..ad60b87a3c69 100644 --- a/include/soc/fsl/qe/ucc_fast.h +++ b/include/soc/fsl/qe/ucc_fast.h @@ -10,7 +10,7 @@ #ifndef __UCC_FAST_H__ #define __UCC_FAST_H__ -#include <linux/kernel.h> +#include <linux/types.h> #include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/qe.h> @@ -146,7 +146,6 @@ struct ucc_fast_info { resource_size_t regs; int irq; u32 uccm_mask; - int bd_mem_part; int brkpt_support; int grant_support; int tsa; diff --git a/include/soc/fsl/qe/ucc_slow.h b/include/soc/fsl/qe/ucc_slow.h index 11a216e4e919..7548ce8a202d 100644 --- a/include/soc/fsl/qe/ucc_slow.h +++ b/include/soc/fsl/qe/ucc_slow.h @@ -11,7 +11,7 @@ #ifndef __UCC_SLOW_H__ #define __UCC_SLOW_H__ -#include <linux/kernel.h> +#include <linux/types.h> #include <soc/fsl/qe/immap_qe.h> #include <soc/fsl/qe/qe.h> diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index cfe00e08e85b..0d3d6beb7fdb 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -256,7 +256,7 @@ struct qm_dqrr_entry { __be32 context_b; struct qm_fd fd; u8 __reserved4[32]; -} __packed; +} __packed __aligned(64); #define QM_DQRR_VERB_VBIT 0x80 #define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */ #define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */ @@ -289,7 +289,7 @@ union qm_mr_entry { __be32 tag; struct qm_fd fd; u8 __reserved1[32]; - } __packed ern; + } __packed __aligned(64) ern; struct { u8 verb; u8 fqs; /* Frame Queue Status */ @@ -689,7 +689,8 @@ enum qman_cb_dqrr_result { }; typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm, struct qman_fq *fq, - const struct qm_dqrr_entry *dqrr); + const struct qm_dqrr_entry *dqrr, + bool sched_napi); /* * This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They @@ -1171,6 +1172,15 @@ int qman_delete_cgr(struct qman_cgr *cgr); void qman_delete_cgr_safe(struct qman_cgr *cgr); /** + * qman_update_cgr_safe - Modifies a congestion group object from any CPU + * @cgr: the 'cgr' object to modify + * @opts: state of the CGR settings + * + * This will select the proper CPU and modify the CGR settings. + */ +int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts); + +/** * qman_query_cgr_congested - Queries CGR's congestion status * @cgr: the 'cgr' object to query * @result: returns 'cgr's congestion status, 1 (true) if congested diff --git a/include/soc/imx/cpu.h b/include/soc/imx/cpu.h index 42d6aeb951fa..0bf610acafd0 100644 --- a/include/soc/imx/cpu.h +++ b/include/soc/imx/cpu.h @@ -9,6 +9,7 @@ #define MXC_CPU_MX27 27 #define MXC_CPU_MX31 31 #define MXC_CPU_MX35 35 +#define MXC_CPU_MX50 50 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 #define MXC_CPU_IMX6SL 0x60 diff --git a/include/soc/imx/revision.h b/include/soc/imx/revision.h index b2a55dafaf0a..b122d2fc8881 100644 --- a/include/soc/imx/revision.h +++ b/include/soc/imx/revision.h @@ -22,6 +22,7 @@ #define IMX_CHIP_REVISION_3_3 0x33 #define IMX_CHIP_REVISION_UNKNOWN 0xff +int mx25_revision(void); int mx27_revision(void); int mx31_revision(void); int mx35_revision(void); diff --git a/include/soc/imx/timer.h b/include/soc/imx/timer.h deleted file mode 100644 index b888d5076b4d..000000000000 --- a/include/soc/imx/timer.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2015 Linaro Ltd. - */ - -#ifndef __SOC_IMX_TIMER_H__ -#define __SOC_IMX_TIMER_H__ - -enum imx_gpt_type { - GPT_TYPE_IMX1, /* i.MX1 */ - GPT_TYPE_IMX21, /* i.MX21/27 */ - GPT_TYPE_IMX31, /* i.MX31/35/25/37/51/6Q */ - GPT_TYPE_IMX6DL, /* i.MX6DL/SX/SL */ -}; - -/* - * This is a stop-gap solution for clock drivers like imx1/imx21 which call - * mxc_timer_init() to initialize timer for non-DT boot. It can be removed - * when these legacy non-DT support is converted or dropped. - */ -void mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type); - -#endif /* __SOC_IMX_TIMER_H__ */ diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h index 5a34b87d89e3..000eb1cf68b7 100644 --- a/include/soc/mediatek/smi.h +++ b/include/soc/mediatek/smi.h @@ -9,37 +9,22 @@ #include <linux/bitops.h> #include <linux/device.h> -#ifdef CONFIG_MTK_SMI +#if IS_ENABLED(CONFIG_MTK_SMI) -#define MTK_LARB_NR_MAX 16 +enum iommu_atf_cmd { + IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to en/disable iommu */ + IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, /* For infra master to enable iommu */ + IOMMU_ATF_CMD_MAX, +}; #define MTK_SMI_MMU_EN(port) BIT(port) struct mtk_smi_larb_iommu { struct device *dev; unsigned int mmu; + unsigned char bank[32]; }; -/* - * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter. - * It also initialize some basic setting(like iommu). - * mtk_smi_larb_put: Disable the power domain and clocks for this local arbiter. - * Both should be called in non-atomic context. - * - * Returns 0 if successful, negative on failure. - */ -int mtk_smi_larb_get(struct device *larbdev); -void mtk_smi_larb_put(struct device *larbdev); - -#else - -static inline int mtk_smi_larb_get(struct device *larbdev) -{ - return 0; -} - -static inline void mtk_smi_larb_put(struct device *larbdev) { } - #endif #endif diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h new file mode 100644 index 000000000000..09722f83b0ca --- /dev/null +++ b/include/soc/microchip/mpfs.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * + * Microchip PolarFire SoC (MPFS) + * + * Copyright (c) 2020 Microchip Corporation. All rights reserved. + * + * Author: Conor Dooley <conor.dooley@microchip.com> + * + */ + +#ifndef __SOC_MPFS_H__ +#define __SOC_MPFS_H__ + +#include <linux/types.h> +#include <linux/of_device.h> + +struct mpfs_sys_controller; + +struct mpfs_mss_msg { + u8 cmd_opcode; + u16 cmd_data_size; + struct mpfs_mss_response *response; + u8 *cmd_data; + u16 mbox_offset; + u16 resp_offset; +}; + +struct mpfs_mss_response { + u32 resp_status; + u32 *resp_msg; + u16 resp_size; +}; + +#if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) + +int mpfs_blocking_transaction(struct mpfs_sys_controller *mpfs_client, struct mpfs_mss_msg *msg); + +struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev); + +struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_client); + +#endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */ + +#if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) + +u32 mpfs_reset_read(struct device *dev); + +void mpfs_reset_write(struct device *dev, u32 val); + +#endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */ + +#endif /* __SOC_MPFS_H__ */ diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 1e9db9577441..1e1b40f4e664 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -11,6 +11,8 @@ #include <linux/regmap.h> #include <net/dsa.h> +struct tc_mqprio_qopt_offload; + /* Port Group IDs (PGID) are masks of destination ports. * * For L2 forwarding, the switch performs 3 lookups in the PGID table for each @@ -51,19 +53,22 @@ */ /* Reserve some destination PGIDs at the end of the range: + * PGID_BLACKHOLE: used for not forwarding the frames * PGID_CPU: used for whitelisting certain MAC addresses, such as the addresses * of the switch port net devices, towards the CPU port module. * PGID_UC: the flooding destinations for unknown unicast traffic. - * PGID_MC: the flooding destinations for broadcast and non-IP multicast - * traffic. + * PGID_MC: the flooding destinations for non-IP multicast traffic. * PGID_MCIPV4: the flooding destinations for IPv4 multicast traffic. * PGID_MCIPV6: the flooding destinations for IPv6 multicast traffic. + * PGID_BC: the flooding destinations for broadcast traffic. */ -#define PGID_CPU 59 -#define PGID_UC 60 -#define PGID_MC 61 -#define PGID_MCIPV4 62 -#define PGID_MCIPV6 63 +#define PGID_BLACKHOLE 57 +#define PGID_CPU 58 +#define PGID_UC 59 +#define PGID_MC 60 +#define PGID_MCIPV4 61 +#define PGID_MCIPV6 62 +#define PGID_BC 63 #define for_each_unicast_dest_pgid(ocelot, pgid) \ for ((pgid) = 0; \ @@ -72,7 +77,7 @@ #define for_each_nonreserved_multicast_dest_pgid(ocelot, pgid) \ for ((pgid) = (ocelot)->num_phys_ports + 1; \ - (pgid) < PGID_CPU; \ + (pgid) < PGID_BLACKHOLE; \ (pgid)++) #define for_each_aggr_pgid(ocelot, pgid) \ @@ -86,22 +91,7 @@ /* Source PGIDs, one per physical port */ #define PGID_SRC 80 -#define IFH_INJ_BYPASS BIT(31) -#define IFH_INJ_POP_CNT_DISABLE (3 << 28) - -#define IFH_TAG_TYPE_C 0 -#define IFH_TAG_TYPE_S 1 - -#define IFH_REW_OP_NOOP 0x0 -#define IFH_REW_OP_DSCP 0x1 -#define IFH_REW_OP_ONE_STEP_PTP 0x2 -#define IFH_REW_OP_TWO_STEP_PTP 0x3 -#define IFH_REW_OP_ORIGIN_PTP 0x5 - -#define OCELOT_TAG_LEN 16 -#define OCELOT_SHORT_PREFIX_LEN 4 -#define OCELOT_LONG_PREFIX_LEN 16 -#define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) +#define OCELOT_NUM_TC 8 #define OCELOT_SPEED_2500 0 #define OCELOT_SPEED_1000 1 @@ -128,6 +118,7 @@ enum ocelot_target { S2, HSIO, PTP, + FDMA, GCB, DEV_GMII, TARGET_MAX, @@ -341,13 +332,61 @@ enum ocelot_reg { SYS_COUNT_RX_64, SYS_COUNT_RX_65_127, SYS_COUNT_RX_128_255, - SYS_COUNT_RX_256_1023, + SYS_COUNT_RX_256_511, + SYS_COUNT_RX_512_1023, SYS_COUNT_RX_1024_1526, SYS_COUNT_RX_1527_MAX, SYS_COUNT_RX_PAUSE, SYS_COUNT_RX_CONTROL, SYS_COUNT_RX_LONGS, SYS_COUNT_RX_CLASSIFIED_DROPS, + SYS_COUNT_RX_RED_PRIO_0, + SYS_COUNT_RX_RED_PRIO_1, + SYS_COUNT_RX_RED_PRIO_2, + SYS_COUNT_RX_RED_PRIO_3, + SYS_COUNT_RX_RED_PRIO_4, + SYS_COUNT_RX_RED_PRIO_5, + SYS_COUNT_RX_RED_PRIO_6, + SYS_COUNT_RX_RED_PRIO_7, + SYS_COUNT_RX_YELLOW_PRIO_0, + SYS_COUNT_RX_YELLOW_PRIO_1, + SYS_COUNT_RX_YELLOW_PRIO_2, + SYS_COUNT_RX_YELLOW_PRIO_3, + SYS_COUNT_RX_YELLOW_PRIO_4, + SYS_COUNT_RX_YELLOW_PRIO_5, + SYS_COUNT_RX_YELLOW_PRIO_6, + SYS_COUNT_RX_YELLOW_PRIO_7, + SYS_COUNT_RX_GREEN_PRIO_0, + SYS_COUNT_RX_GREEN_PRIO_1, + SYS_COUNT_RX_GREEN_PRIO_2, + SYS_COUNT_RX_GREEN_PRIO_3, + SYS_COUNT_RX_GREEN_PRIO_4, + SYS_COUNT_RX_GREEN_PRIO_5, + SYS_COUNT_RX_GREEN_PRIO_6, + SYS_COUNT_RX_GREEN_PRIO_7, + SYS_COUNT_RX_ASSEMBLY_ERRS, + SYS_COUNT_RX_SMD_ERRS, + SYS_COUNT_RX_ASSEMBLY_OK, + SYS_COUNT_RX_MERGE_FRAGMENTS, + SYS_COUNT_RX_PMAC_OCTETS, + SYS_COUNT_RX_PMAC_UNICAST, + SYS_COUNT_RX_PMAC_MULTICAST, + SYS_COUNT_RX_PMAC_BROADCAST, + SYS_COUNT_RX_PMAC_SHORTS, + SYS_COUNT_RX_PMAC_FRAGMENTS, + SYS_COUNT_RX_PMAC_JABBERS, + SYS_COUNT_RX_PMAC_CRC_ALIGN_ERRS, + SYS_COUNT_RX_PMAC_SYM_ERRS, + SYS_COUNT_RX_PMAC_64, + SYS_COUNT_RX_PMAC_65_127, + SYS_COUNT_RX_PMAC_128_255, + SYS_COUNT_RX_PMAC_256_511, + SYS_COUNT_RX_PMAC_512_1023, + SYS_COUNT_RX_PMAC_1024_1526, + SYS_COUNT_RX_PMAC_1527_MAX, + SYS_COUNT_RX_PMAC_PAUSE, + SYS_COUNT_RX_PMAC_CONTROL, + SYS_COUNT_RX_PMAC_LONGS, SYS_COUNT_TX_OCTETS, SYS_COUNT_TX_UNICAST, SYS_COUNT_TX_MULTICAST, @@ -357,11 +396,64 @@ enum ocelot_reg { SYS_COUNT_TX_PAUSE, SYS_COUNT_TX_64, SYS_COUNT_TX_65_127, - SYS_COUNT_TX_128_511, + SYS_COUNT_TX_128_255, + SYS_COUNT_TX_256_511, SYS_COUNT_TX_512_1023, SYS_COUNT_TX_1024_1526, SYS_COUNT_TX_1527_MAX, - SYS_COUNT_TX_AGING, + SYS_COUNT_TX_YELLOW_PRIO_0, + SYS_COUNT_TX_YELLOW_PRIO_1, + SYS_COUNT_TX_YELLOW_PRIO_2, + SYS_COUNT_TX_YELLOW_PRIO_3, + SYS_COUNT_TX_YELLOW_PRIO_4, + SYS_COUNT_TX_YELLOW_PRIO_5, + SYS_COUNT_TX_YELLOW_PRIO_6, + SYS_COUNT_TX_YELLOW_PRIO_7, + SYS_COUNT_TX_GREEN_PRIO_0, + SYS_COUNT_TX_GREEN_PRIO_1, + SYS_COUNT_TX_GREEN_PRIO_2, + SYS_COUNT_TX_GREEN_PRIO_3, + SYS_COUNT_TX_GREEN_PRIO_4, + SYS_COUNT_TX_GREEN_PRIO_5, + SYS_COUNT_TX_GREEN_PRIO_6, + SYS_COUNT_TX_GREEN_PRIO_7, + SYS_COUNT_TX_AGED, + SYS_COUNT_TX_MM_HOLD, + SYS_COUNT_TX_MERGE_FRAGMENTS, + SYS_COUNT_TX_PMAC_OCTETS, + SYS_COUNT_TX_PMAC_UNICAST, + SYS_COUNT_TX_PMAC_MULTICAST, + SYS_COUNT_TX_PMAC_BROADCAST, + SYS_COUNT_TX_PMAC_PAUSE, + SYS_COUNT_TX_PMAC_64, + SYS_COUNT_TX_PMAC_65_127, + SYS_COUNT_TX_PMAC_128_255, + SYS_COUNT_TX_PMAC_256_511, + SYS_COUNT_TX_PMAC_512_1023, + SYS_COUNT_TX_PMAC_1024_1526, + SYS_COUNT_TX_PMAC_1527_MAX, + SYS_COUNT_DROP_LOCAL, + SYS_COUNT_DROP_TAIL, + SYS_COUNT_DROP_YELLOW_PRIO_0, + SYS_COUNT_DROP_YELLOW_PRIO_1, + SYS_COUNT_DROP_YELLOW_PRIO_2, + SYS_COUNT_DROP_YELLOW_PRIO_3, + SYS_COUNT_DROP_YELLOW_PRIO_4, + SYS_COUNT_DROP_YELLOW_PRIO_5, + SYS_COUNT_DROP_YELLOW_PRIO_6, + SYS_COUNT_DROP_YELLOW_PRIO_7, + SYS_COUNT_DROP_GREEN_PRIO_0, + SYS_COUNT_DROP_GREEN_PRIO_1, + SYS_COUNT_DROP_GREEN_PRIO_2, + SYS_COUNT_DROP_GREEN_PRIO_3, + SYS_COUNT_DROP_GREEN_PRIO_4, + SYS_COUNT_DROP_GREEN_PRIO_5, + SYS_COUNT_DROP_GREEN_PRIO_6, + SYS_COUNT_DROP_GREEN_PRIO_7, + SYS_COUNT_SF_MATCHING_FRAMES, + SYS_COUNT_SF_NOT_PASSING_FRAMES, + SYS_COUNT_SF_NOT_PASSING_SDU, + SYS_COUNT_SF_RED_FRAMES, SYS_RESET_CFG, SYS_SR_ETYPE_CFG, SYS_VLAN_ETYPE_CFG, @@ -384,7 +476,6 @@ enum ocelot_reg { SYS_MMGT_FAST, SYS_EVENTS_DIF, SYS_EVENTS_CORE, - SYS_CNT, SYS_PTP_STATUS, SYS_PTP_TXSTAMP, SYS_PTP_NXT, @@ -426,6 +517,9 @@ enum ocelot_reg { DEV_MAC_FC_MAC_LOW_CFG, DEV_MAC_FC_MAC_HIGH_CFG, DEV_MAC_STICKY, + DEV_MM_ENABLE_CONFIG, + DEV_MM_VERIF_CONFIG, + DEV_MM_STATUS, PCS1G_CFG, PCS1G_MODE_CFG, PCS1G_SD_CFG, @@ -544,11 +638,6 @@ enum ocelot_ptp_pins { TOD_ACC_PIN }; -struct ocelot_stat_layout { - u32 offset; - char name[ETH_GSTRING_LEN]; -}; - enum ocelot_tag_prefix { OCELOT_TAG_PREFIX_DISABLED = 0, OCELOT_TAG_PREFIX_NONE, @@ -557,66 +646,188 @@ enum ocelot_tag_prefix { }; struct ocelot; +struct device_node; struct ocelot_ops { struct net_device *(*port_to_netdev)(struct ocelot *ocelot, int port); int (*netdev_to_port)(struct net_device *dev); int (*reset)(struct ocelot *ocelot); u16 (*wm_enc)(u16 value); + u16 (*wm_dec)(u16 value); + void (*wm_stat)(u32 val, u32 *inuse, u32 *maxuse); + void (*psfp_init)(struct ocelot *ocelot); + int (*psfp_filter_add)(struct ocelot *ocelot, int port, + struct flow_cls_offload *f); + int (*psfp_filter_del)(struct ocelot *ocelot, struct flow_cls_offload *f); + int (*psfp_stats_get)(struct ocelot *ocelot, struct flow_cls_offload *f, + struct flow_stats *stats); + void (*cut_through_fwd)(struct ocelot *ocelot); + void (*tas_clock_adjust)(struct ocelot *ocelot); + void (*tas_guard_bands_update)(struct ocelot *ocelot, int port); + void (*update_stats)(struct ocelot *ocelot); +}; + +struct ocelot_vcap_policer { + struct list_head pol_list; + u16 base; + u16 max; + u16 base2; + u16 max2; }; struct ocelot_vcap_block { struct list_head rules; int count; - int pol_lpr; }; +struct ocelot_bridge_vlan { + u16 vid; + unsigned long portmask; + unsigned long untagged; + struct list_head list; +}; + +enum ocelot_port_tag_config { + /* all VLANs are egress-untagged */ + OCELOT_PORT_TAG_DISABLED = 0, + /* all VLANs except the native VLAN and VID 0 are egress-tagged */ + OCELOT_PORT_TAG_NATIVE = 1, + /* all VLANs except VID 0 are egress-tagged */ + OCELOT_PORT_TAG_TRUNK_NO_VID0 = 2, + /* all VLANs are egress-tagged */ + OCELOT_PORT_TAG_TRUNK = 3, +}; + +struct ocelot_psfp_list { + struct list_head stream_list; + struct list_head sfi_list; + struct list_head sgi_list; + /* Serialize access to the lists */ + struct mutex lock; +}; + +enum ocelot_sb { + OCELOT_SB_BUF, + OCELOT_SB_REF, + OCELOT_SB_NUM, +}; + +enum ocelot_sb_pool { + OCELOT_SB_POOL_ING, + OCELOT_SB_POOL_EGR, + OCELOT_SB_POOL_NUM, +}; + +/* MAC table entry types. + * ENTRYTYPE_NORMAL is subject to aging. + * ENTRYTYPE_LOCKED is not subject to aging. + * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast. + * ENTRYTYPE_MACv6 is not subject to aging. For IPv6 multicast. + */ +enum macaccess_entry_type { + ENTRYTYPE_NORMAL = 0, + ENTRYTYPE_LOCKED, + ENTRYTYPE_MACv4, + ENTRYTYPE_MACv6, +}; + +enum ocelot_proto { + OCELOT_PROTO_PTP_L2 = BIT(0), + OCELOT_PROTO_PTP_L4 = BIT(1), +}; + +#define OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION BIT(0) +#define OCELOT_QUIRK_QSGMII_PORTS_MUST_BE_UP BIT(1) + +struct ocelot_lag_fdb { + unsigned char addr[ETH_ALEN]; + u16 vid; + struct net_device *bond; + struct list_head list; +}; + +struct ocelot_mirror { + refcount_t refcount; + int to; +}; + +struct ocelot_mm_state { + enum ethtool_mm_verify_status verify_status; + bool tx_enabled; + bool tx_active; + u8 preemptible_tcs; + u8 active_preemptible_tcs; +}; + +struct ocelot_port; + struct ocelot_port { struct ocelot *ocelot; struct regmap *target; - bool vlan_aware; + struct net_device *bond; + struct net_device *bridge; - /* Ingress default VLAN (pvid) */ - u16 pvid; + struct ocelot_port *dsa_8021q_cpu; - /* Egress default VLAN (vid) */ - u16 vid; + /* VLAN that untagged frames are classified to, on ingress */ + const struct ocelot_bridge_vlan *pvid_vlan; - u8 ptp_cmd; + struct tc_taprio_qopt_offload *taprio; + + phy_interface_t phy_mode; + + unsigned int ptp_skbs_in_flight; struct sk_buff_head tx_skbs; + + unsigned int trap_proto; + + u16 mrp_ring_id; + + u8 ptp_cmd; u8 ts_id; - spinlock_t ts_id_lock; - phy_interface_t phy_mode; + u8 index; + + u8 stp_state; + bool vlan_aware; + bool is_dsa_8021q_cpu; + bool learn_ena; + + bool lag_tx_active; + + int bridge_num; - u8 *xmit_template; + int speed; }; struct ocelot { struct device *dev; + struct devlink *devlink; + struct devlink_port *devlink_ports; const struct ocelot_ops *ops; struct regmap *targets[TARGET_MAX]; struct regmap_field *regfields[REGFIELD_MAX]; const u32 *const *map; - const struct ocelot_stat_layout *stats_layout; - unsigned int num_stats; + struct list_head stats_regions; - int shared_queue_sz; + u32 pool_size[OCELOT_SB_NUM][OCELOT_SB_POOL_NUM]; + int packet_buffer_size; + int num_frame_refs; int num_mact_rows; - struct net_device *hw_bridge_dev; - u16 bridge_mask; - u16 bridge_fwd_mask; - struct ocelot_port **ports; u8 base_mac[ETH_ALEN]; - /* Keep track of the vlan port masks */ - u32 vlan_mask[VLAN_N_VID]; + struct list_head vlans; + struct list_head traps; + struct list_head lag_fdbs; + + /* Switches like VSC9959 have flooding per traffic class */ + int num_flooding_pgids; /* In tables like ANA:PORT and the ANA:PGID:PGID mask, * the CPU is located after the physical ports (at the @@ -626,32 +837,55 @@ struct ocelot { int npi; - enum ocelot_tag_prefix inj_prefix; - enum ocelot_tag_prefix xtr_prefix; + enum ocelot_tag_prefix npi_inj_prefix; + enum ocelot_tag_prefix npi_xtr_prefix; - u32 *lags; + unsigned long bridges; struct list_head multicast; + struct list_head pgids; struct list_head dummy_rules; struct ocelot_vcap_block block[3]; + struct ocelot_vcap_policer vcap_pol; struct vcap_props *vcap; + struct ocelot_mirror *mirror; - /* Workqueue to check statistics for overflow with its lock */ - struct mutex stats_lock; - u64 *stats; + struct ocelot_psfp_list psfp; + + /* Workqueue to check statistics for overflow */ struct delayed_work stats_work; struct workqueue_struct *stats_queue; + /* Lock for serializing access to the statistics array */ + spinlock_t stats_lock; + u64 *stats; + + /* Lock for serializing indirect access to STAT_VIEW registers */ + struct mutex stat_view_lock; + /* Lock for serializing access to the MAC table */ + struct mutex mact_lock; + /* Lock for serializing forwarding domain changes, including the + * configuration of the Time-Aware Shaper, MAC Merge layer and + * cut-through forwarding, on which it depends + */ + struct mutex fwd_domain_lock; + + struct workqueue_struct *owq; u8 ptp:1; + u8 mm_supported:1; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_info; - struct hwtstamp_config hwtstamp_config; - /* Protects the PTP interface state */ - struct mutex ptp_lock; + unsigned int ptp_skbs_in_flight; + /* Protects the 2-step TX timestamp ID logic */ + spinlock_t ts_id_lock; /* Protects the PTP clock */ spinlock_t ptp_clock_lock; struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM]; + + struct ocelot_mm_state *mm; + + struct ocelot_fdma *fdma; }; struct ocelot_policer { @@ -659,25 +893,42 @@ struct ocelot_policer { u32 burst; /* bytes */ }; -#define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -#define ocelot_read_gix(ocelot, reg, gi) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi)) -#define ocelot_read_rix(ocelot, reg, ri) __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri)) -#define ocelot_read(ocelot, reg) __ocelot_read_ix(ocelot, reg, 0) +#define ocelot_bulk_read(ocelot, reg, buf, count) \ + __ocelot_bulk_read_ix(ocelot, reg, 0, buf, count) -#define ocelot_write_ix(ocelot, val, reg, gi, ri) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -#define ocelot_write_gix(ocelot, val, reg, gi) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi)) -#define ocelot_write_rix(ocelot, val, reg, ri) __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri)) +#define ocelot_read_ix(ocelot, reg, gi, ri) \ + __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) +#define ocelot_read_gix(ocelot, reg, gi) \ + __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi)) +#define ocelot_read_rix(ocelot, reg, ri) \ + __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri)) +#define ocelot_read(ocelot, reg) \ + __ocelot_read_ix(ocelot, reg, 0) + +#define ocelot_write_ix(ocelot, val, reg, gi, ri) \ + __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) +#define ocelot_write_gix(ocelot, val, reg, gi) \ + __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi)) +#define ocelot_write_rix(ocelot, val, reg, ri) \ + __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri)) #define ocelot_write(ocelot, val, reg) __ocelot_write_ix(ocelot, val, reg, 0) -#define ocelot_rmw_ix(ocelot, val, m, reg, gi, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -#define ocelot_rmw_gix(ocelot, val, m, reg, gi) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi)) -#define ocelot_rmw_rix(ocelot, val, m, reg, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri)) +#define ocelot_rmw_ix(ocelot, val, m, reg, gi, ri) \ + __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) +#define ocelot_rmw_gix(ocelot, val, m, reg, gi) \ + __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi)) +#define ocelot_rmw_rix(ocelot, val, m, reg, ri) \ + __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri)) #define ocelot_rmw(ocelot, val, m, reg) __ocelot_rmw_ix(ocelot, val, m, reg, 0) -#define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val)) -#define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val)) -#define ocelot_fields_write(ocelot, id, reg, val) regmap_fields_write((ocelot)->regfields[(reg)], (id), (val)) -#define ocelot_fields_read(ocelot, id, reg, val) regmap_fields_read((ocelot)->regfields[(reg)], (id), (val)) +#define ocelot_field_write(ocelot, reg, val) \ + regmap_field_write((ocelot)->regfields[(reg)], (val)) +#define ocelot_field_read(ocelot, reg, val) \ + regmap_field_read((ocelot)->regfields[(reg)], (val)) +#define ocelot_fields_write(ocelot, id, reg, val) \ + regmap_fields_write((ocelot)->regfields[(reg)], (id), (val)) +#define ocelot_fields_read(ocelot, id, reg, val) \ + regmap_fields_read((ocelot)->regfields[(reg)], (id), (val)) #define ocelot_target_read_ix(ocelot, target, reg, gi, ri) \ __ocelot_target_read_ix(ocelot, target, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) @@ -698,64 +949,125 @@ struct ocelot_policer { __ocelot_target_write_ix(ocelot, target, val, reg, 0) /* I/O */ -u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); -void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); -u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset); -void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset); -void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, - u32 offset); +u32 ocelot_port_readl(struct ocelot_port *port, enum ocelot_reg reg); +void ocelot_port_writel(struct ocelot_port *port, u32 val, enum ocelot_reg reg); +void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, + enum ocelot_reg reg); +int __ocelot_bulk_read_ix(struct ocelot *ocelot, enum ocelot_reg reg, + u32 offset, void *buf, int count); +u32 __ocelot_read_ix(struct ocelot *ocelot, enum ocelot_reg reg, u32 offset); +void __ocelot_write_ix(struct ocelot *ocelot, u32 val, enum ocelot_reg reg, + u32 offset); +void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, + enum ocelot_reg reg, u32 offset); u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target, u32 reg, u32 offset); void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target, u32 val, u32 reg, u32 offset); +/* Packet I/O */ +bool ocelot_can_inject(struct ocelot *ocelot, int grp); +void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, + u32 rew_op, struct sk_buff *skb); +void ocelot_ifh_port_set(void *ifh, int port, u32 rew_op, u32 vlan_tag); +int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **skb); +void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp); +void ocelot_ptp_rx_timestamp(struct ocelot *ocelot, struct sk_buff *skb, + u64 timestamp); + /* Hardware initialization */ int ocelot_regfields_init(struct ocelot *ocelot, const struct reg_field *const regfields); struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res); +int ocelot_reset(struct ocelot *ocelot); int ocelot_init(struct ocelot *ocelot); void ocelot_deinit(struct ocelot *ocelot); void ocelot_init_port(struct ocelot *ocelot, int port); void ocelot_deinit_port(struct ocelot *ocelot, int port); +void ocelot_port_setup_dsa_8021q_cpu(struct ocelot *ocelot, int cpu); +void ocelot_port_teardown_dsa_8021q_cpu(struct ocelot *ocelot, int cpu); +void ocelot_port_assign_dsa_8021q_cpu(struct ocelot *ocelot, int port, int cpu); +void ocelot_port_unassign_dsa_8021q_cpu(struct ocelot *ocelot, int port); +u32 ocelot_port_assigned_dsa_8021q_cpu_mask(struct ocelot *ocelot, int port); + +/* Watermark interface */ +u16 ocelot_wm_enc(u16 value); +u16 ocelot_wm_dec(u16 wm); +void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse); + /* DSA callbacks */ -void ocelot_port_enable(struct ocelot *ocelot, int port, - struct phy_device *phy); -void ocelot_port_disable(struct ocelot *ocelot, int port); void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data); void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data); int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset); +void ocelot_port_get_stats64(struct ocelot *ocelot, int port, + struct rtnl_link_stats64 *stats); +void ocelot_port_get_pause_stats(struct ocelot *ocelot, int port, + struct ethtool_pause_stats *pause_stats); +void ocelot_port_get_mm_stats(struct ocelot *ocelot, int port, + struct ethtool_mm_stats *stats); +void ocelot_port_get_rmon_stats(struct ocelot *ocelot, int port, + struct ethtool_rmon_stats *rmon_stats, + const struct ethtool_rmon_hist_range **ranges); +void ocelot_port_get_eth_ctrl_stats(struct ocelot *ocelot, int port, + struct ethtool_eth_ctrl_stats *ctrl_stats); +void ocelot_port_get_eth_mac_stats(struct ocelot *ocelot, int port, + struct ethtool_eth_mac_stats *mac_stats); +void ocelot_port_get_eth_phy_stats(struct ocelot *ocelot, int port, + struct ethtool_eth_phy_stats *phy_stats); int ocelot_get_ts_info(struct ocelot *ocelot, int port, struct ethtool_ts_info *info); void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs); -void ocelot_adjust_link(struct ocelot *ocelot, int port, - struct phy_device *phydev); int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, bool enabled, - struct switchdev_trans *trans); + struct netlink_ext_ack *extack); void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state); +u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port); +int ocelot_port_pre_bridge_flags(struct ocelot *ocelot, int port, + struct switchdev_brport_flags val); +void ocelot_port_bridge_flags(struct ocelot *ocelot, int port, + struct switchdev_brport_flags val); +int ocelot_port_get_default_prio(struct ocelot *ocelot, int port); +int ocelot_port_set_default_prio(struct ocelot *ocelot, int port, u8 prio); +int ocelot_port_get_dscp_prio(struct ocelot *ocelot, int port, u8 dscp); +int ocelot_port_add_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio); +int ocelot_port_del_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio); int ocelot_port_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge); -int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, - struct net_device *bridge); + struct net_device *bridge, int bridge_num, + struct netlink_ext_ack *extack); +void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, + struct net_device *bridge); +int ocelot_mact_flush(struct ocelot *ocelot, int port); int ocelot_fdb_dump(struct ocelot *ocelot, int port, dsa_fdb_dump_cb_t *cb, void *data); -int ocelot_fdb_add(struct ocelot *ocelot, int port, - const unsigned char *addr, u16 vid); -int ocelot_fdb_del(struct ocelot *ocelot, int port, - const unsigned char *addr, u16 vid); +int ocelot_fdb_add(struct ocelot *ocelot, int port, const unsigned char *addr, + u16 vid, const struct net_device *bridge); +int ocelot_fdb_del(struct ocelot *ocelot, int port, const unsigned char *addr, + u16 vid, const struct net_device *bridge); +int ocelot_lag_fdb_add(struct ocelot *ocelot, struct net_device *bond, + const unsigned char *addr, u16 vid, + const struct net_device *bridge); +int ocelot_lag_fdb_del(struct ocelot *ocelot, struct net_device *bond, + const unsigned char *addr, u16 vid, + const struct net_device *bridge); +int ocelot_vlan_prepare(struct ocelot *ocelot, int port, u16 vid, bool pvid, + bool untagged, struct netlink_ext_ack *extack); int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, bool untagged); int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid); int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); -void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, - struct sk_buff *clone); +int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, + struct sk_buff *skb, + struct sk_buff **clone); void ocelot_get_txtstamp(struct ocelot *ocelot); void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu); int ocelot_get_max_mtu(struct ocelot *ocelot, int port); int ocelot_port_policer_add(struct ocelot *ocelot, int port, struct ocelot_policer *pol); int ocelot_port_policer_del(struct ocelot *ocelot, int port); +int ocelot_port_mirror_add(struct ocelot *ocelot, int from, int to, + bool ingress, struct netlink_ext_ack *extack); +void ocelot_port_mirror_del(struct ocelot *ocelot, int from, bool ingress); int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, struct flow_cls_offload *f, bool ingress); int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port, @@ -763,8 +1075,134 @@ int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port, int ocelot_cls_flower_stats(struct ocelot *ocelot, int port, struct flow_cls_offload *f, bool ingress); int ocelot_port_mdb_add(struct ocelot *ocelot, int port, - const struct switchdev_obj_port_mdb *mdb); + const struct switchdev_obj_port_mdb *mdb, + const struct net_device *bridge); int ocelot_port_mdb_del(struct ocelot *ocelot, int port, - const struct switchdev_obj_port_mdb *mdb); + const struct switchdev_obj_port_mdb *mdb, + const struct net_device *bridge); +int ocelot_port_lag_join(struct ocelot *ocelot, int port, + struct net_device *bond, + struct netdev_lag_upper_info *info, + struct netlink_ext_ack *extack); +void ocelot_port_lag_leave(struct ocelot *ocelot, int port, + struct net_device *bond); +void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active); +int ocelot_bond_get_id(struct ocelot *ocelot, struct net_device *bond); + +int ocelot_devlink_sb_register(struct ocelot *ocelot); +void ocelot_devlink_sb_unregister(struct ocelot *ocelot); +int ocelot_sb_pool_get(struct ocelot *ocelot, unsigned int sb_index, + u16 pool_index, + struct devlink_sb_pool_info *pool_info); +int ocelot_sb_pool_set(struct ocelot *ocelot, unsigned int sb_index, + u16 pool_index, u32 size, + enum devlink_sb_threshold_type threshold_type, + struct netlink_ext_ack *extack); +int ocelot_sb_port_pool_get(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 pool_index, + u32 *p_threshold); +int ocelot_sb_port_pool_set(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 pool_index, + u32 threshold, struct netlink_ext_ack *extack); +int ocelot_sb_tc_pool_bind_get(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 tc_index, + enum devlink_sb_pool_type pool_type, + u16 *p_pool_index, u32 *p_threshold); +int ocelot_sb_tc_pool_bind_set(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 tc_index, + enum devlink_sb_pool_type pool_type, + u16 pool_index, u32 threshold, + struct netlink_ext_ack *extack); +int ocelot_sb_occ_snapshot(struct ocelot *ocelot, unsigned int sb_index); +int ocelot_sb_occ_max_clear(struct ocelot *ocelot, unsigned int sb_index); +int ocelot_sb_occ_port_pool_get(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 pool_index, + u32 *p_cur, u32 *p_max); +int ocelot_sb_occ_tc_port_bind_get(struct ocelot *ocelot, int port, + unsigned int sb_index, u16 tc_index, + enum devlink_sb_pool_type pool_type, + u32 *p_cur, u32 *p_max); + +int ocelot_port_configure_serdes(struct ocelot *ocelot, int port, + struct device_node *portnp); + +void ocelot_phylink_mac_config(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + const struct phylink_link_state *state); +void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + phy_interface_t interface, + unsigned long quirks); +void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port, + struct phy_device *phydev, + unsigned int link_an_mode, + phy_interface_t interface, + int speed, int duplex, + bool tx_pause, bool rx_pause, + unsigned long quirks); + +int ocelot_mact_lookup(struct ocelot *ocelot, int *dst_idx, + const unsigned char mac[ETH_ALEN], + unsigned int vid, enum macaccess_entry_type *type); +int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx, + const unsigned char mac[ETH_ALEN], + unsigned int vid, + enum macaccess_entry_type type, + int sfid, int ssid); + +int ocelot_migrate_mdbs(struct ocelot *ocelot, unsigned long from_mask, + unsigned long to_mask); + +int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix, + struct ocelot_policer *pol); +int ocelot_vcap_policer_del(struct ocelot *ocelot, u32 pol_ix); + +void ocelot_mm_irq(struct ocelot *ocelot); +int ocelot_port_set_mm(struct ocelot *ocelot, int port, + struct ethtool_mm_cfg *cfg, + struct netlink_ext_ack *extack); +int ocelot_port_get_mm(struct ocelot *ocelot, int port, + struct ethtool_mm_state *state); +int ocelot_port_mqprio(struct ocelot *ocelot, int port, + struct tc_mqprio_qopt_offload *mqprio); + +#if IS_ENABLED(CONFIG_BRIDGE_MRP) +int ocelot_mrp_add(struct ocelot *ocelot, int port, + const struct switchdev_obj_mrp *mrp); +int ocelot_mrp_del(struct ocelot *ocelot, int port, + const struct switchdev_obj_mrp *mrp); +int ocelot_mrp_add_ring_role(struct ocelot *ocelot, int port, + const struct switchdev_obj_ring_role_mrp *mrp); +int ocelot_mrp_del_ring_role(struct ocelot *ocelot, int port, + const struct switchdev_obj_ring_role_mrp *mrp); +#else +static inline int ocelot_mrp_add(struct ocelot *ocelot, int port, + const struct switchdev_obj_mrp *mrp) +{ + return -EOPNOTSUPP; +} + +static inline int ocelot_mrp_del(struct ocelot *ocelot, int port, + const struct switchdev_obj_mrp *mrp) +{ + return -EOPNOTSUPP; +} + +static inline int +ocelot_mrp_add_ring_role(struct ocelot *ocelot, int port, + const struct switchdev_obj_ring_role_mrp *mrp) +{ + return -EOPNOTSUPP; +} + +static inline int +ocelot_mrp_del_ring_role(struct ocelot *ocelot, int port, + const struct switchdev_obj_ring_role_mrp *mrp) +{ + return -EOPNOTSUPP; +} +#endif + +void ocelot_pll5_init(struct ocelot *ocelot); #endif diff --git a/include/soc/mscc/ocelot_ana.h b/include/soc/mscc/ocelot_ana.h index 1669481d9779..67e0ae05a5ab 100644 --- a/include/soc/mscc/ocelot_ana.h +++ b/include/soc/mscc/ocelot_ana.h @@ -227,6 +227,11 @@ #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(x) ((x) & GENMASK(1, 0)) #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M GENMASK(1, 0) +#define SFIDACCESS_CMD_IDLE 0 +#define SFIDACCESS_CMD_READ 1 +#define SFIDACCESS_CMD_WRITE 2 +#define SFIDACCESS_CMD_INIT 3 + #define ANA_TABLES_SFIDTIDX_SGID_VALID BIT(26) #define ANA_TABLES_SFIDTIDX_SGID(x) (((x) << 18) & GENMASK(25, 18)) #define ANA_TABLES_SFIDTIDX_SGID_M GENMASK(25, 18) @@ -255,6 +260,11 @@ #define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 21) & GENMASK(24, 21)) #define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(24, 21) #define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(24, 21)) >> 21) +#define ANA_SG_CONFIG_REG_3_IPV_VALID BIT(24) +#define ANA_SG_CONFIG_REG_3_IPV_INVALID(x) (((x) << 24) & GENMASK(24, 24)) +#define ANA_SG_CONFIG_REG_3_INIT_IPV(x) (((x) << 21) & GENMASK(23, 21)) +#define ANA_SG_CONFIG_REG_3_INIT_IPV_M GENMASK(23, 21) +#define ANA_SG_CONFIG_REG_3_INIT_IPV_X(x) (((x) & GENMASK(23, 21)) >> 21) #define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(25) #define ANA_SG_GCL_GS_CONFIG_RSZ 0x4 diff --git a/include/soc/mscc/ocelot_dev.h b/include/soc/mscc/ocelot_dev.h index 0c6021f02fee..fcf02baa76b2 100644 --- a/include/soc/mscc/ocelot_dev.h +++ b/include/soc/mscc/ocelot_dev.h @@ -93,6 +93,29 @@ #define DEV_MAC_STICKY_TX_FRM_LEN_OVR_STICKY BIT(1) #define DEV_MAC_STICKY_TX_ABORT_STICKY BIT(0) +#define DEV_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA BIT(0) +#define DEV_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA BIT(4) +#define DEV_MM_CONFIG_ENABLE_CONFIG_KEEP_S_AFTER_D BIT(8) + +#define DEV_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_DIS BIT(0) +#define DEV_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME(x) (((x) << 4) & GENMASK(11, 4)) +#define DEV_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_M GENMASK(11, 4) +#define DEV_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_X(x) (((x) & GENMASK(11, 4)) >> 4) +#define DEV_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS(x) (((x) << 12) & GENMASK(13, 12)) +#define DEV_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_M GENMASK(13, 12) +#define DEV_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_X(x) (((x) & GENMASK(13, 12)) >> 12) + +#define DEV_MM_STAT_MM_STATUS_PRMPT_ACTIVE_STATUS BIT(0) +#define DEV_MM_STAT_MM_STATUS_PRMPT_ACTIVE_STICKY BIT(4) +#define DEV_MM_STAT_MM_STATUS_PRMPT_VERIFY_STATE(x) (((x) << 8) & GENMASK(10, 8)) +#define DEV_MM_STAT_MM_STATUS_PRMPT_VERIFY_STATE_M GENMASK(10, 8) +#define DEV_MM_STAT_MM_STATUS_PRMPT_VERIFY_STATE_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define DEV_MM_STAT_MM_STATUS_UNEXP_RX_PFRM_STICKY BIT(12) +#define DEV_MM_STAT_MM_STATUS_UNEXP_TX_PFRM_STICKY BIT(16) +#define DEV_MM_STAT_MM_STATUS_MM_RX_FRAME_STATUS BIT(20) +#define DEV_MM_STAT_MM_STATUS_MM_TX_FRAME_STATUS BIT(24) +#define DEV_MM_STAT_MM_STATUS_MM_TX_PRMPT_STATUS BIT(28) + #define PCS1G_CFG_LINK_STATUS_TYPE BIT(4) #define PCS1G_CFG_AN_LINK_CTRL_ENA BIT(1) #define PCS1G_CFG_PCS_ENA BIT(0) diff --git a/include/soc/mscc/ocelot_ptp.h b/include/soc/mscc/ocelot_ptp.h index 6a7388fa7cc5..f085884b1fa2 100644 --- a/include/soc/mscc/ocelot_ptp.h +++ b/include/soc/mscc/ocelot_ptp.h @@ -13,6 +13,9 @@ #include <linux/ptp_clock_kernel.h> #include <soc/mscc/ocelot.h> +#define OCELOT_MAX_PTP_ID 63 +#define OCELOT_PTP_FIFO_SIZE 128 + #define PTP_PIN_CFG_RSZ 0x20 #define PTP_PIN_TOD_SEC_MSB_RSZ PTP_PIN_CFG_RSZ #define PTP_PIN_TOD_SEC_LSB_RSZ PTP_PIN_CFG_RSZ @@ -37,8 +40,6 @@ enum { #define PTP_CFG_MISC_PTP_EN BIT(2) -#define PSEC_PER_SEC 1000000000000LL - #define PTP_CFG_CLK_ADJ_CFG_ENA BIT(0) #define PTP_CFG_CLK_ADJ_CFG_DIR BIT(1) diff --git a/include/soc/mscc/ocelot_qsys.h b/include/soc/mscc/ocelot_qsys.h index a814bc2017d8..9731895be643 100644 --- a/include/soc/mscc/ocelot_qsys.h +++ b/include/soc/mscc/ocelot_qsys.h @@ -71,11 +71,8 @@ #define QSYS_RES_STAT_GSZ 0x8 -#define QSYS_RES_STAT_INUSE(x) (((x) << 12) & GENMASK(23, 12)) -#define QSYS_RES_STAT_INUSE_M GENMASK(23, 12) -#define QSYS_RES_STAT_INUSE_X(x) (((x) & GENMASK(23, 12)) >> 12) -#define QSYS_RES_STAT_MAXUSE(x) ((x) & GENMASK(11, 0)) -#define QSYS_RES_STAT_MAXUSE_M GENMASK(11, 0) +#define QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(x) ((x) & GENMASK(15, 0)) +#define QSYS_MMGT_EQ_CTRL_FP_FREE_CNT_M GENMASK(15, 0) #define QSYS_EVENTS_CORE_EV_FDC(x) (((x) << 2) & GENMASK(4, 2)) #define QSYS_EVENTS_CORE_EV_FDC_M GENMASK(4, 2) diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h index 96300adf3648..c601a4598b0d 100644 --- a/include/soc/mscc/ocelot_vcap.h +++ b/include/soc/mscc/ocelot_vcap.h @@ -8,6 +8,20 @@ #include <soc/mscc/ocelot.h> +/* Cookie definitions for private VCAP filters installed by the driver. + * Must be unique per VCAP block. + */ +#define OCELOT_VCAP_ES0_TAG_8021Q_RXVLAN(ocelot, port, upstream) ((upstream) << 16 | (port)) +#define OCELOT_VCAP_IS1_TAG_8021Q_TXVLAN(ocelot, port) (port) +#define OCELOT_VCAP_IS2_TAG_8021Q_TXVLAN(ocelot, port) (port) +#define OCELOT_VCAP_IS2_MRP_REDIRECT(ocelot, port) ((ocelot)->num_phys_ports + (port)) +#define OCELOT_VCAP_IS2_MRP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2) +#define OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2 + 1) +#define OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2 + 2) +#define OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2 + 3) +#define OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2 + 4) +#define OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot) ((ocelot)->num_phys_ports * 2 + 5) + /* ================================================================= * VCAP Common * ================================================================= @@ -400,4 +414,318 @@ enum vcap_es0_action_field { VCAP_ES0_ACT_HIT_STICKY, }; +struct ocelot_ipv4 { + u8 addr[4]; +}; + +enum ocelot_vcap_bit { + OCELOT_VCAP_BIT_ANY, + OCELOT_VCAP_BIT_0, + OCELOT_VCAP_BIT_1 +}; + +struct ocelot_vcap_u8 { + u8 value[1]; + u8 mask[1]; +}; + +struct ocelot_vcap_u16 { + u8 value[2]; + u8 mask[2]; +}; + +struct ocelot_vcap_u24 { + u8 value[3]; + u8 mask[3]; +}; + +struct ocelot_vcap_u32 { + u8 value[4]; + u8 mask[4]; +}; + +struct ocelot_vcap_u40 { + u8 value[5]; + u8 mask[5]; +}; + +struct ocelot_vcap_u48 { + u8 value[6]; + u8 mask[6]; +}; + +struct ocelot_vcap_u64 { + u8 value[8]; + u8 mask[8]; +}; + +struct ocelot_vcap_u128 { + u8 value[16]; + u8 mask[16]; +}; + +struct ocelot_vcap_vid { + u16 value; + u16 mask; +}; + +struct ocelot_vcap_ipv4 { + struct ocelot_ipv4 value; + struct ocelot_ipv4 mask; +}; + +struct ocelot_vcap_udp_tcp { + u16 value; + u16 mask; +}; + +struct ocelot_vcap_port { + u8 value; + u8 mask; +}; + +enum ocelot_vcap_key_type { + OCELOT_VCAP_KEY_ANY, + OCELOT_VCAP_KEY_ETYPE, + OCELOT_VCAP_KEY_LLC, + OCELOT_VCAP_KEY_SNAP, + OCELOT_VCAP_KEY_ARP, + OCELOT_VCAP_KEY_IPV4, + OCELOT_VCAP_KEY_IPV6 +}; + +struct ocelot_vcap_key_vlan { + struct ocelot_vcap_vid vid; /* VLAN ID (12 bit) */ + struct ocelot_vcap_u8 pcp; /* PCP (3 bit) */ + enum ocelot_vcap_bit dei; /* DEI */ + enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */ +}; + +struct ocelot_vcap_key_etype { + struct ocelot_vcap_u48 dmac; + struct ocelot_vcap_u48 smac; + struct ocelot_vcap_u16 etype; + struct ocelot_vcap_u16 data; /* MAC data */ +}; + +struct ocelot_vcap_key_llc { + struct ocelot_vcap_u48 dmac; + struct ocelot_vcap_u48 smac; + + /* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */ + struct ocelot_vcap_u32 llc; +}; + +struct ocelot_vcap_key_snap { + struct ocelot_vcap_u48 dmac; + struct ocelot_vcap_u48 smac; + + /* SNAP header: Organization Code at byte 0, Type at byte 3 */ + struct ocelot_vcap_u40 snap; +}; + +struct ocelot_vcap_key_arp { + struct ocelot_vcap_u48 smac; + enum ocelot_vcap_bit arp; /* Opcode ARP/RARP */ + enum ocelot_vcap_bit req; /* Opcode request/reply */ + enum ocelot_vcap_bit unknown; /* Opcode unknown */ + enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */ + enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */ + + /**< Protocol addr. length 4, hardware length 6 */ + enum ocelot_vcap_bit length; + + enum ocelot_vcap_bit ip; /* Protocol address type IP */ + enum ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */ + struct ocelot_vcap_ipv4 sip; /* Sender IP address */ + struct ocelot_vcap_ipv4 dip; /* Target IP address */ +}; + +struct ocelot_vcap_key_ipv4 { + enum ocelot_vcap_bit ttl; /* TTL zero */ + enum ocelot_vcap_bit fragment; /* Fragment */ + enum ocelot_vcap_bit options; /* Header options */ + struct ocelot_vcap_u8 ds; + struct ocelot_vcap_u8 proto; /* Protocol */ + struct ocelot_vcap_ipv4 sip; /* Source IP address */ + struct ocelot_vcap_ipv4 dip; /* Destination IP address */ + struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ + struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */ + struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */ + enum ocelot_vcap_bit tcp_fin; + enum ocelot_vcap_bit tcp_syn; + enum ocelot_vcap_bit tcp_rst; + enum ocelot_vcap_bit tcp_psh; + enum ocelot_vcap_bit tcp_ack; + enum ocelot_vcap_bit tcp_urg; + enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ + enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ + enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ +}; + +struct ocelot_vcap_key_ipv6 { + struct ocelot_vcap_u8 proto; /* IPv6 protocol */ + struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */ + struct ocelot_vcap_u128 dip; /* IPv6 destination (byte 0-7 ignored) */ + enum ocelot_vcap_bit ttl; /* TTL zero */ + struct ocelot_vcap_u8 ds; + struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ + struct ocelot_vcap_udp_tcp sport; + struct ocelot_vcap_udp_tcp dport; + enum ocelot_vcap_bit tcp_fin; + enum ocelot_vcap_bit tcp_syn; + enum ocelot_vcap_bit tcp_rst; + enum ocelot_vcap_bit tcp_psh; + enum ocelot_vcap_bit tcp_ack; + enum ocelot_vcap_bit tcp_urg; + enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ + enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ + enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ +}; + +enum ocelot_mask_mode { + OCELOT_MASK_MODE_NONE, + OCELOT_MASK_MODE_PERMIT_DENY, + OCELOT_MASK_MODE_POLICY, + OCELOT_MASK_MODE_REDIRECT, +}; + +enum ocelot_es0_vid_sel { + OCELOT_ES0_VID_PLUS_CLASSIFIED_VID = 0, + OCELOT_ES0_VID = 1, +}; + +enum ocelot_es0_pcp_sel { + OCELOT_CLASSIFIED_PCP = 0, + OCELOT_ES0_PCP = 1, +}; + +enum ocelot_es0_tag { + OCELOT_NO_ES0_TAG, + OCELOT_ES0_TAG, + OCELOT_FORCE_PORT_TAG, + OCELOT_FORCE_UNTAG, +}; + +enum ocelot_tag_tpid_sel { + OCELOT_TAG_TPID_SEL_8021Q, + OCELOT_TAG_TPID_SEL_8021AD, +}; + +struct ocelot_vcap_action { + union { + /* VCAP ES0 */ + struct { + enum ocelot_es0_tag push_outer_tag; + enum ocelot_es0_tag push_inner_tag; + enum ocelot_tag_tpid_sel tag_a_tpid_sel; + int tag_a_vid_sel; + int tag_a_pcp_sel; + u16 vid_a_val; + u8 pcp_a_val; + u8 dei_a_val; + enum ocelot_tag_tpid_sel tag_b_tpid_sel; + int tag_b_vid_sel; + int tag_b_pcp_sel; + u16 vid_b_val; + u8 pcp_b_val; + u8 dei_b_val; + }; + + /* VCAP IS1 */ + struct { + bool vid_replace_ena; + u16 vid; + bool vlan_pop_cnt_ena; + int vlan_pop_cnt; + bool pcp_dei_ena; + u8 pcp; + u8 dei; + bool qos_ena; + u8 qos_val; + u8 pag_override_mask; + u8 pag_val; + }; + + /* VCAP IS2 */ + struct { + bool cpu_copy_ena; + u8 cpu_qu_num; + enum ocelot_mask_mode mask_mode; + unsigned long port_mask; + bool police_ena; + bool mirror_ena; + struct ocelot_policer pol; + u32 pol_ix; + }; + }; +}; + +struct ocelot_vcap_stats { + u64 bytes; + u64 pkts; + u64 used; +}; + +enum ocelot_vcap_filter_type { + OCELOT_VCAP_FILTER_DUMMY, + OCELOT_VCAP_FILTER_PAG, + OCELOT_VCAP_FILTER_OFFLOAD, + OCELOT_PSFP_FILTER_OFFLOAD, +}; + +struct ocelot_vcap_id { + unsigned long cookie; + bool tc_offload; +}; + +struct ocelot_vcap_filter { + struct list_head list; + + enum ocelot_vcap_filter_type type; + int block_id; + int goto_target; + int lookup; + u8 pag; + u16 prio; + struct ocelot_vcap_id id; + + struct ocelot_vcap_action action; + struct ocelot_vcap_stats stats; + /* For VCAP IS1 and IS2 */ + bool take_ts; + bool is_trap; + unsigned long ingress_port_mask; + /* For VCAP ES0 */ + struct ocelot_vcap_port ingress_port; + /* For VCAP IS2 mirrors and ES0 */ + struct ocelot_vcap_port egress_port; + + enum ocelot_vcap_bit dmac_mc; + enum ocelot_vcap_bit dmac_bc; + struct ocelot_vcap_key_vlan vlan; + + enum ocelot_vcap_key_type key_type; + union { + /* OCELOT_VCAP_KEY_ANY: No specific fields */ + struct ocelot_vcap_key_etype etype; + struct ocelot_vcap_key_llc llc; + struct ocelot_vcap_key_snap snap; + struct ocelot_vcap_key_arp arp; + struct ocelot_vcap_key_ipv4 ipv4; + struct ocelot_vcap_key_ipv6 ipv6; + } key; +}; + +int ocelot_vcap_filter_add(struct ocelot *ocelot, + struct ocelot_vcap_filter *rule, + struct netlink_ext_ack *extack); +int ocelot_vcap_filter_del(struct ocelot *ocelot, + struct ocelot_vcap_filter *rule); +int ocelot_vcap_filter_replace(struct ocelot *ocelot, + struct ocelot_vcap_filter *filter); +struct ocelot_vcap_filter * +ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, + unsigned long cookie, bool tc_offload); + #endif /* _OCELOT_VCAP_H_ */ diff --git a/include/soc/mscc/vsc7514_regs.h b/include/soc/mscc/vsc7514_regs.h new file mode 100644 index 000000000000..ffe343a9c04b --- /dev/null +++ b/include/soc/mscc/vsc7514_regs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2021 Innovative Advantage Inc. + */ + +#ifndef VSC7514_REGS_H +#define VSC7514_REGS_H + +#include <soc/mscc/ocelot_vcap.h> + +extern struct vcap_props vsc7514_vcap_props[]; + +extern const struct reg_field vsc7514_regfields[REGFIELD_MAX]; + +extern const u32 *vsc7514_regmap[TARGET_MAX]; + +#endif diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h deleted file mode 100644 index 8c18dc6d3fde..000000000000 --- a/include/soc/nps/common.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2016, Mellanox Technologies. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef SOC_NPS_COMMON_H -#define SOC_NPS_COMMON_H - -#ifdef CONFIG_SMP -#define NPS_IPI_IRQ 5 -#endif - -#define NPS_HOST_REG_BASE 0xF6000000 - -#define NPS_MSU_BLKID 0x018 - -#define CTOP_INST_RSPI_GIC_0_R12 0x3C56117E -#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST 0x5B60 -#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM 0x00010422 - -#ifndef AUX_IENABLE -#define AUX_IENABLE 0x40c -#endif - -#define CTOP_AUX_IACK (0xFFFFF800 + 0x088) - -#ifndef __ASSEMBLY__ - -/* In order to increase compilation test coverage */ -#ifdef CONFIG_ARC -static inline void nps_ack_gic(void) -{ - __asm__ __volatile__ ( - " .word %0\n" - : - : "i"(CTOP_INST_RSPI_GIC_0_R12) - : "memory"); -} -#else -static inline void nps_ack_gic(void) { } -#define write_aux_reg(r, v) -#define read_aux_reg(r) 0 -#endif - -/* CPU global ID */ -struct global_id { - union { - struct { -#ifdef CONFIG_EZNPS_MTM_EXT - u32 __reserved:20, cluster:4, core:4, thread:4; -#else - u32 __reserved:24, cluster:4, core:4; -#endif - }; - u32 value; - }; -}; - -/* - * Convert logical to physical CPU IDs - * - * The conversion swap bits 1 and 2 of cluster id (out of 4 bits) - * Now quad of logical clusters id's are adjacent physically, - * and not like the id's physically came with each cluster. - * Below table is 4x4 mesh of core clusters as it layout on chip. - * Cluster ids are in format: logical (physical) - * - * ----------------- ------------------ - * 3 | 5 (3) 7 (7) | | 13 (11) 15 (15)| - * - * 2 | 4 (2) 6 (6) | | 12 (10) 14 (14)| - * ----------------- ------------------ - * 1 | 1 (1) 3 (5) | | 9 (9) 11 (13)| - * - * 0 | 0 (0) 2 (4) | | 8 (8) 10 (12)| - * ----------------- ------------------ - * 0 1 2 3 - */ -static inline int nps_cluster_logic_to_phys(int cluster) -{ -#ifdef __arc__ - __asm__ __volatile__( - " mov r3,%0\n" - " .short %1\n" - " .word %2\n" - " mov %0,r3\n" - : "+r"(cluster) - : "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST), - "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM) - : "r3"); -#endif - - return cluster; -} - -#define NPS_CPU_TO_CLUSTER_NUM(cpu) \ - ({ struct global_id gid; gid.value = cpu; \ - nps_cluster_logic_to_phys(gid.cluster); }) - -struct nps_host_reg_address { - union { - struct { - u32 base:8, cl_x:4, cl_y:4, - blkid:6, reg:8, __reserved:2; - }; - u32 value; - }; -}; - -struct nps_host_reg_address_non_cl { - union { - struct { - u32 base:7, blkid:11, reg:12, __reserved:2; - }; - u32 value; - }; -}; - -static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg) -{ - struct nps_host_reg_address_non_cl reg_address; - - reg_address.value = NPS_HOST_REG_BASE; - reg_address.blkid = blkid; - reg_address.reg = reg; - - return (void *)reg_address.value; -} - -static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg) -{ - struct nps_host_reg_address reg_address; - u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu); - - reg_address.value = NPS_HOST_REG_BASE; - reg_address.cl_x = (cl >> 2) & 0x3; - reg_address.cl_y = cl & 0x3; - reg_address.blkid = blkid; - reg_address.reg = reg; - - return (void *)reg_address.value; -} -#endif /* __ASSEMBLY__ */ - -#endif /* SOC_NPS_COMMON_H */ diff --git a/include/soc/nps/mtm.h b/include/soc/nps/mtm.h deleted file mode 100644 index d2f5e7e3703e..000000000000 --- a/include/soc/nps/mtm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016, Mellanox Technologies. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef SOC_NPS_MTM_H -#define SOC_NPS_MTM_H - -#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF -#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3 - -static inline void hw_schd_save(unsigned int *flags) -{ - __asm__ __volatile__( - " .word %1\n" - " st r3,[%0]\n" - : - : "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3) - : "r3", "memory"); -} - -static inline void hw_schd_restore(unsigned int flags) -{ - __asm__ __volatile__( - " mov r3, %0\n" - " .word %1\n" - : - : "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3) - : "r3"); -} - -#endif /* SOC_NPS_MTM_H */ diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h new file mode 100644 index 000000000000..5870a94599a2 --- /dev/null +++ b/include/soc/qcom/ice.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef __QCOM_ICE_H__ +#define __QCOM_ICE_H__ + +#include <linux/types.h> + +struct qcom_ice; + +enum qcom_ice_crypto_key_size { + QCOM_ICE_CRYPTO_KEY_SIZE_INVALID = 0x0, + QCOM_ICE_CRYPTO_KEY_SIZE_128 = 0x1, + QCOM_ICE_CRYPTO_KEY_SIZE_192 = 0x2, + QCOM_ICE_CRYPTO_KEY_SIZE_256 = 0x3, + QCOM_ICE_CRYPTO_KEY_SIZE_512 = 0x4, +}; + +enum qcom_ice_crypto_alg { + QCOM_ICE_CRYPTO_ALG_AES_XTS = 0x0, + QCOM_ICE_CRYPTO_ALG_BITLOCKER_AES_CBC = 0x1, + QCOM_ICE_CRYPTO_ALG_AES_ECB = 0x2, + QCOM_ICE_CRYPTO_ALG_ESSIV_AES_CBC = 0x3, +}; + +int qcom_ice_enable(struct qcom_ice *ice); +int qcom_ice_resume(struct qcom_ice *ice); +int qcom_ice_suspend(struct qcom_ice *ice); +int qcom_ice_program_key(struct qcom_ice *ice, + u8 algorithm_id, u8 key_size, + const u8 crypto_key[], u8 data_unit_size, + int slot); +int qcom_ice_evict_key(struct qcom_ice *ice, int slot); +struct qcom_ice *of_qcom_ice_get(struct device *dev); +#endif /* __QCOM_ICE_H__ */ diff --git a/include/soc/qcom/qcom-spmi-pmic.h b/include/soc/qcom/qcom-spmi-pmic.h new file mode 100644 index 000000000000..a62d500a6fda --- /dev/null +++ b/include/soc/qcom/qcom-spmi-pmic.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2022 Linaro. All rights reserved. + * Author: Caleb Connolly <caleb.connolly@linaro.org> + */ + +#ifndef __QCOM_SPMI_PMIC_H__ +#define __QCOM_SPMI_PMIC_H__ + +#include <linux/device.h> + +#define COMMON_SUBTYPE 0x00 +#define PM8941_SUBTYPE 0x01 +#define PM8841_SUBTYPE 0x02 +#define PM8019_SUBTYPE 0x03 +#define PM8226_SUBTYPE 0x04 +#define PM8110_SUBTYPE 0x05 +#define PMA8084_SUBTYPE 0x06 +#define PMI8962_SUBTYPE 0x07 +#define PMD9635_SUBTYPE 0x08 +#define PM8994_SUBTYPE 0x09 +#define PMI8994_SUBTYPE 0x0a +#define PM8916_SUBTYPE 0x0b +#define PM8004_SUBTYPE 0x0c +#define PM8909_SUBTYPE 0x0d +#define PM8028_SUBTYPE 0x0e +#define PM8901_SUBTYPE 0x0f +#define PM8950_SUBTYPE 0x10 +#define PMI8950_SUBTYPE 0x11 +#define PMK8001_SUBTYPE 0x12 +#define PMI8996_SUBTYPE 0x13 +#define PM8998_SUBTYPE 0x14 +#define PMI8998_SUBTYPE 0x15 +#define PM8005_SUBTYPE 0x18 +#define PM8937_SUBTYPE 0x19 +#define PM660L_SUBTYPE 0x1a +#define PM660_SUBTYPE 0x1b +#define PM8150_SUBTYPE 0x1e +#define PM8150L_SUBTYPE 0x1f +#define PM8150B_SUBTYPE 0x20 +#define PMK8002_SUBTYPE 0x21 +#define PM8009_SUBTYPE 0x24 +#define PMI632_SUBTYPE 0x25 +#define PM8150C_SUBTYPE 0x26 +#define PM6150_SUBTYPE 0x28 +#define SMB2351_SUBTYPE 0x29 +#define PM8008_SUBTYPE 0x2c +#define PM6125_SUBTYPE 0x2d +#define PM7250B_SUBTYPE 0x2e +#define PMK8350_SUBTYPE 0x2f +#define PMR735B_SUBTYPE 0x34 +#define PM6350_SUBTYPE 0x36 +#define PM4125_SUBTYPE 0x37 + +#define PMI8998_FAB_ID_SMIC 0x11 +#define PMI8998_FAB_ID_GF 0x30 + +#define PM660_FAB_ID_GF 0x0 +#define PM660_FAB_ID_TSMC 0x2 +#define PM660_FAB_ID_MX 0x3 + +struct qcom_spmi_pmic { + unsigned int type; + unsigned int subtype; + unsigned int major; + unsigned int minor; + unsigned int rev2; + unsigned int fab_id; + const char *name; +}; + +const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev); + +#endif /* __QCOM_SPMI_PMIC_H__ */ diff --git a/include/soc/qcom/spm.h b/include/soc/qcom/spm.h new file mode 100644 index 000000000000..5b263c685812 --- /dev/null +++ b/include/soc/qcom/spm.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014,2015, Linaro Ltd. + */ + +#ifndef __SPM_H__ +#define __SPM_H__ + +enum pm_sleep_mode { + PM_SLEEP_MODE_STBY, + PM_SLEEP_MODE_RET, + PM_SLEEP_MODE_SPC, + PM_SLEEP_MODE_PC, + PM_SLEEP_MODE_NR, +}; + +struct spm_driver_data; +void spm_set_low_power_mode(struct spm_driver_data *drv, + enum pm_sleep_mode mode); + +#endif /* __SPM_H__ */ diff --git a/include/soc/qcom/tcs.h b/include/soc/qcom/tcs.h index 7a2a055ba6b0..3acca067c72b 100644 --- a/include/soc/qcom/tcs.h +++ b/include/soc/qcom/tcs.h @@ -30,7 +30,13 @@ enum rpmh_state { * * @addr: the address of the resource slv_id:18:16 | offset:0:15 * @data: the resource state request - * @wait: wait for this request to be complete before sending the next + * @wait: ensure that this command is complete before returning. + * Setting "wait" here only makes sense during rpmh_write_batch() for + * active-only transfers, this is because: + * rpmh_write() - Always waits. + * (DEFINE_RPMH_MSG_ONSTACK will set .wait_for_compl) + * rpmh_write_async() - Never waits. + * (There's no request completion callback) */ struct tcs_cmd { u32 addr; @@ -43,6 +49,7 @@ struct tcs_cmd { * * @state: state for the request. * @wait_for_compl: wait until we get a response from the h/w accelerator + * (same as setting cmd->wait for all commands in the request) * @num_cmds: the number of @cmds in this request * @cmds: an array of tcs_cmds */ diff --git a/include/soc/rockchip/pm_domains.h b/include/soc/rockchip/pm_domains.h new file mode 100644 index 000000000000..7dbd941fc937 --- /dev/null +++ b/include/soc/rockchip/pm_domains.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2022, The Chromium OS Authors. All rights reserved. + */ + +#ifndef __SOC_ROCKCHIP_PM_DOMAINS_H__ +#define __SOC_ROCKCHIP_PM_DOMAINS_H__ + +#ifdef CONFIG_ROCKCHIP_PM_DOMAINS + +int rockchip_pmu_block(void); +void rockchip_pmu_unblock(void); + +#else /* CONFIG_ROCKCHIP_PM_DOMAINS */ + +static inline int rockchip_pmu_block(void) +{ + return 0; +} + +static inline void rockchip_pmu_unblock(void) { } + +#endif /* CONFIG_ROCKCHIP_PM_DOMAINS */ + +#endif /* __SOC_ROCKCHIP_PM_DOMAINS_H__ */ diff --git a/include/soc/rockchip/rk3399_grf.h b/include/soc/rockchip/rk3399_grf.h index 3eebabcb2812..39cd44cec982 100644 --- a/include/soc/rockchip/rk3399_grf.h +++ b/include/soc/rockchip/rk3399_grf.h @@ -11,11 +11,8 @@ /* PMU GRF Registers */ #define RK3399_PMUGRF_OS_REG2 0x308 -#define RK3399_PMUGRF_DDRTYPE_SHIFT 13 -#define RK3399_PMUGRF_DDRTYPE_MASK 7 -#define RK3399_PMUGRF_DDRTYPE_DDR3 3 -#define RK3399_PMUGRF_DDRTYPE_LPDDR2 5 -#define RK3399_PMUGRF_DDRTYPE_LPDDR3 6 -#define RK3399_PMUGRF_DDRTYPE_LPDDR4 7 +#define RK3399_PMUGRF_OS_REG2_DDRTYPE GENMASK(15, 13) +#define RK3399_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2) +#define RK3399_PMUGRF_OS_REG2_BW_CH1 GENMASK(19, 18) #endif diff --git a/include/soc/rockchip/rk3568_grf.h b/include/soc/rockchip/rk3568_grf.h new file mode 100644 index 000000000000..52853efd6720 --- /dev/null +++ b/include/soc/rockchip/rk3568_grf.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef __SOC_RK3568_GRF_H +#define __SOC_RK3568_GRF_H + +#define RK3568_PMUGRF_OS_REG2 0x208 +#define RK3568_PMUGRF_OS_REG2_DRAMTYPE_INFO GENMASK(15, 13) +#define RK3568_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2) + +#define RK3568_PMUGRF_OS_REG3 0x20c +#define RK3568_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3 GENMASK(13, 12) +#define RK3568_PMUGRF_OS_REG3_SYSREG_VERSION GENMASK(31, 28) + +#endif /* __SOC_RK3568_GRF_H */ diff --git a/include/soc/rockchip/rk3588_grf.h b/include/soc/rockchip/rk3588_grf.h new file mode 100644 index 000000000000..630b35a55064 --- /dev/null +++ b/include/soc/rockchip/rk3588_grf.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef __SOC_RK3588_GRF_H +#define __SOC_RK3588_GRF_H + +#define RK3588_PMUGRF_OS_REG2 0x208 +#define RK3588_PMUGRF_OS_REG2_DRAMTYPE_INFO GENMASK(15, 13) +#define RK3588_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2) +#define RK3588_PMUGRF_OS_REG2_BW_CH1 GENMASK(19, 18) +#define RK3588_PMUGRF_OS_REG2_CH_INFO GENMASK(29, 28) + +#define RK3588_PMUGRF_OS_REG3 0x20c +#define RK3588_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3 GENMASK(13, 12) +#define RK3588_PMUGRF_OS_REG3_SYSREG_VERSION GENMASK(31, 28) + +#define RK3588_PMUGRF_OS_REG4 0x210 +#define RK3588_PMUGRF_OS_REG5 0x214 + +#endif /* __SOC_RK3588_GRF_H */ diff --git a/include/soc/rockchip/rockchip_grf.h b/include/soc/rockchip/rockchip_grf.h new file mode 100644 index 000000000000..e46fd72aea8d --- /dev/null +++ b/include/soc/rockchip/rockchip_grf.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Rockchip General Register Files definitions + */ + +#ifndef __SOC_ROCKCHIP_GRF_H +#define __SOC_ROCKCHIP_GRF_H + +/* Rockchip DDRTYPE defines */ +enum { + ROCKCHIP_DDRTYPE_DDR3 = 3, + ROCKCHIP_DDRTYPE_LPDDR2 = 5, + ROCKCHIP_DDRTYPE_LPDDR3 = 6, + ROCKCHIP_DDRTYPE_LPDDR4 = 7, + ROCKCHIP_DDRTYPE_LPDDR4X = 8, +}; + +#endif /* __SOC_ROCKCHIP_GRF_H */ diff --git a/include/soc/sifive/sifive_ccache.h b/include/soc/sifive/sifive_ccache.h new file mode 100644 index 000000000000..4d4ed49388a0 --- /dev/null +++ b/include/soc/sifive/sifive_ccache.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * SiFive Composable Cache Controller header file + * + */ + +#ifndef __SOC_SIFIVE_CCACHE_H +#define __SOC_SIFIVE_CCACHE_H + +extern int register_sifive_ccache_error_notifier(struct notifier_block *nb); +extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb); + +#define SIFIVE_CCACHE_ERR_TYPE_CE 0 +#define SIFIVE_CCACHE_ERR_TYPE_UE 1 + +#endif /* __SOC_SIFIVE_CCACHE_H */ diff --git a/include/soc/sifive/sifive_l2_cache.h b/include/soc/sifive/sifive_l2_cache.h deleted file mode 100644 index 92ade10ed67e..000000000000 --- a/include/soc/sifive/sifive_l2_cache.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * SiFive L2 Cache Controller header file - * - */ - -#ifndef __SOC_SIFIVE_L2_CACHE_H -#define __SOC_SIFIVE_L2_CACHE_H - -extern int register_sifive_l2_error_notifier(struct notifier_block *nb); -extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); - -#define SIFIVE_L2_ERR_TYPE_CE 0 -#define SIFIVE_L2_ERR_TYPE_UE 1 - -#endif /* __SOC_SIFIVE_L2_CACHE_H */ diff --git a/include/soc/starfive/reset-starfive-jh71x0.h b/include/soc/starfive/reset-starfive-jh71x0.h new file mode 100644 index 000000000000..47b486ececc5 --- /dev/null +++ b/include/soc/starfive/reset-starfive-jh71x0.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __SOC_STARFIVE_RESET_JH71X0_H +#define __SOC_STARFIVE_RESET_JH71X0_H + +#include <linux/auxiliary_bus.h> +#include <linux/compiler_types.h> +#include <linux/container_of.h> + +struct jh71x0_reset_adev { + void __iomem *base; + struct auxiliary_device adev; +}; + +#define to_jh71x0_reset_adev(_adev) \ + container_of((_adev), struct jh71x0_reset_adev, adev) + +#endif diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h index bff99f23860c..6b995a8f0f6d 100644 --- a/include/soc/tegra/bpmp-abi.h +++ b/include/soc/tegra/bpmp-abi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved. */ #ifndef ABI_BPMP_ABI_H @@ -74,6 +74,32 @@ /** * @ingroup MRQ_Format + * Request an answer from the peer. + * This should be set in mrq_request::flags for all requests targetted + * at BPMP. For requests originating in BPMP, this flag is optional except + * for messages targeting MCE, for which the field must be set. + * When this flag is not set, the remote peer must not send a response + * back. + */ +#define BPMP_MAIL_DO_ACK (1U << 0U) + +/** + * @ingroup MRQ_Format + * Ring the sender's doorbell when responding. This should be set unless + * the sender wants to poll the underlying communications layer directly. + * + * An optional direction that can be specified in mrq_request::flags. + */ +#define BPMP_MAIL_RING_DB (1U << 1U) + +/** + * @ingroup MRQ_Format + * CRC present + */ +#define BPMP_MAIL_CRC_PRESENT (1U << 2U) + +/** + * @ingroup MRQ_Format * @brief Header for an MRQ message * * Provides the MRQ number for the MRQ message: #mrq. The remainder of @@ -85,12 +111,139 @@ struct mrq_request { uint32_t mrq; /** - * @brief Flags providing follow up directions to the receiver + * @brief 32bit word containing a number of fields as follows: + * + * struct { + * uint8_t options:4; + * uint8_t xid:4; + * uint8_t payload_length; + * uint16_t crc16; + * }; + * + * **options** directions to the receiver and indicates CRC presence. + * + * #BPMP_MAIL_DO_ACK and #BPMP_MAIL_RING_DB see documentation of respective options. + * #BPMP_MAIL_CRC_PRESENT is supported on T234 and later platforms. It indicates the + * crc16, xid and length fields are present when set. + * Some platform configurations, especially when targeted to applications requiring + * functional safety, mandate this option being set or otherwise will respond with + * -BPMP_EBADMSG and ignore the request. + * + * **xid** is a transaction ID. + * + * Only used when #BPMP_MAIL_CRC_PRESENT is set. + * + * **payload_length** of the message expressed in bytes without the size of this header. + * See table below for minimum accepted payload lengths for each MRQ. + * Note: For DMCE communication, this field expresses the length as a multiple of 4 bytes + * rather than bytes. + * + * Only used when #BPMP_MAIL_CRC_PRESENT is set. + * + * | MRQ | CMD | minimum payload length + * | -------------------- | ------------------------------------ | ------------------------------------------ | + * | MRQ_PING | | 4 | + * | MRQ_THREADED_PING | | 4 | + * | MRQ_RESET | any | 8 | + * | MRQ_I2C | | 12 + cmd_i2c_xfer_request.data_size | + * | MRQ_CLK | CMD_CLK_GET_RATE | 4 | + * | MRQ_CLK | CMD_CLK_SET_RATE | 16 | + * | MRQ_CLK | CMD_CLK_ROUND_RATE | 16 | + * | MRQ_CLK | CMD_CLK_GET_PARENT | 4 | + * | MRQ_CLK | CMD_CLK_SET_PARENT | 8 | + * | MRQ_CLK | CMD_CLK_ENABLE | 4 | + * | MRQ_CLK | CMD_CLK_DISABLE | 4 | + * | MRQ_CLK | CMD_CLK_IS_ENABLED | 4 | + * | MRQ_CLK | CMD_CLK_GET_ALL_INFO | 4 | + * | MRQ_CLK | CMD_CLK_GET_MAX_CLK_ID | 4 | + * | MRQ_CLK | CMD_CLK_GET_FMAX_AT_VMIN | 4 | + * | MRQ_QUERY_ABI | | 4 | + * | MRQ_PG | CMD_PG_QUERY_ABI | 12 | + * | MRQ_PG | CMD_PG_SET_STATE | 12 | + * | MRQ_PG | CMD_PG_GET_STATE | 8 | + * | MRQ_PG | CMD_PG_GET_NAME | 8 | + * | MRQ_PG | CMD_PG_GET_MAX_ID | 8 | + * | MRQ_THERMAL | CMD_THERMAL_QUERY_ABI | 8 | + * | MRQ_THERMAL | CMD_THERMAL_GET_TEMP | 8 | + * | MRQ_THERMAL | CMD_THERMAL_SET_TRIP | 20 | + * | MRQ_THERMAL | CMD_THERMAL_GET_NUM_ZONES | 4 | + * | MRQ_THERMAL | CMD_THERMAL_GET_THERMTRIP | 8 | + * | MRQ_CPU_VHINT | | 8 | + * | MRQ_ABI_RATCHET | | 2 | + * | MRQ_EMC_DVFS_LATENCY | | 8 | + * | MRQ_EMC_DVFS_EMCHUB | | 8 | + * | MRQ_EMC_DISP_RFL | | 4 | + * | MRQ_BWMGR | CMD_BWMGR_QUERY_ABI | 8 | + * | MRQ_BWMGR | CMD_BWMGR_CALC_RATE | 8 + 8 * bwmgr_rate_req.num_iso_clients | + * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_QUERY_ABI | 8 | + * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_CALCULATE_LA | 16 | + * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_SET_LA | 16 | + * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_GET_MAX_BW | 8 | + * | MRQ_CPU_NDIV_LIMITS | | 4 | + * | MRQ_CPU_AUTO_CC3 | | 4 | + * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 | + * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_READ | 5 | + * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len | + * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_GET_FIFO | 4 | + * | MRQ_STRAP | STRAP_SET | 12 | + * | MRQ_UPHY | CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 | + * | MRQ_UPHY | CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 | + * | MRQ_UPHY | CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 | + * | MRQ_UPHY | CMD_UPHY_PCIE_CONTROLLER_STATE | 6 | + * | MRQ_UPHY | CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 | + * | MRQ_FMON | CMD_FMON_GEAR_CLAMP | 16 | + * | MRQ_FMON | CMD_FMON_GEAR_FREE | 4 | + * | MRQ_FMON | CMD_FMON_GEAR_GET | 4 | + * | MRQ_FMON | CMD_FMON_FAULT_STS_GET | 8 | + * | MRQ_EC | CMD_EC_STATUS_EX_GET | 12 | + * | MRQ_QUERY_FW_TAG | | 0 | + * | MRQ_DEBUG | CMD_DEBUG_OPEN_RO | 4 + length of cmd_debug_fopen_request.name | + * | MRQ_DEBUG | CMD_DEBUG_OPEN_WO | 4 + length of cmd_debug_fopen_request.name | + * | MRQ_DEBUG | CMD_DEBUG_READ | 8 | + * | MRQ_DEBUG | CMD_DEBUG_WRITE | 12 + cmd_debug_fwrite_request.datalen | + * | MRQ_DEBUG | CMD_DEBUG_CLOSE | 8 | + * | MRQ_TELEMETRY | | 8 | + * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_QUERY_ABI | 8 | + * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_SET | 20 | + * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_GET | 16 | + * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_CURR_CAP | 8 | + * | MRQ_GEARS | | 0 | + * | MRQ_BWMGR_INT | CMD_BWMGR_INT_QUERY_ABI | 8 | + * | MRQ_BWMGR_INT | CMD_BWMGR_INT_CALC_AND_SET | 16 | + * | MRQ_BWMGR_INT | CMD_BWMGR_INT_CAP_SET | 8 | + * | MRQ_OC_STATUS | | 0 | + * + * **crc16** + * + * CRC16 using polynomial x^16 + x^14 + x^12 + x^11 + x^8 + x^5 + x^4 + x^2 + 1 + * and initialization value 0x4657. The CRC is calculated over all bytes of the message + * including this header. However the crc16 field is considered to be set to 0 when + * calculating the CRC. Only used when #BPMP_MAIL_CRC_PRESENT is set. If + * #BPMP_MAIL_CRC_PRESENT is set and this field does not match the CRC as + * calculated by BPMP, -BPMP_EBADMSG will be returned and the request will + * be ignored. See code snippet below on how to calculate the CRC. * - * | Bit | Description | - * |-----|--------------------------------------------| - * | 1 | ring the sender's doorbell when responding | - * | 0 | should be 1 | + * @code + * uint16_t calc_crc_digest(uint16_t crc, uint8_t *data, size_t size) + * { + * for (size_t i = 0; i < size; i++) { + * crc ^= data[i] << 8; + * for (size_t j = 0; j < 8; j++) { + * if ((crc & 0x8000) == 0x8000) { + * crc = (crc << 1) ^ 0xAC9A; + * } else { + * crc = (crc << 1); + * } + * } + * } + * return crc; + * } + * + * uint16_t calc_crc(uint8_t *data, size_t size) + * { + * return calc_crc_digest(0x4657, data, size); + * } + * @endcode */ uint32_t flags; } BPMP_ABI_PACKED; @@ -107,7 +260,35 @@ struct mrq_request { struct mrq_response { /** @brief Error code for the MRQ request itself */ int32_t err; - /** @brief Reserved for future use */ + + /** + * @brief 32bit word containing a number of fields as follows: + * + * struct { + * uint8_t options:4; + * uint8_t xid:4; + * uint8_t payload_length; + * uint16_t crc16; + * }; + * + * **options** indicates CRC presence. + * + * #BPMP_MAIL_CRC_PRESENT is supported on T234 and later platforms and + * indicates the crc16 related fields are present when set. + * + * **xid** is the transaction ID as sent by the requestor. + * + * **length** of the message expressed in bytes without the size of this header. + * Note: For DMCE communication, this field expresses the length as a multiple of 4 bytes + * rather than bytes. + * + * **crc16** + * + * CRC16 using polynomial x^16 + x^14 + x^12 + x^11 + x^8 + x^5 + x^4 + x^2 + 1 + * and initialization value 0x4657. The CRC is calculated over all bytes of the message + * including this header. However the crc16 field is considered to be set to 0 when + * calculating the CRC. Only used when #BPMP_MAIL_CRC_PRESENT is set. + */ uint32_t flags; } BPMP_ABI_PACKED; @@ -131,24 +312,16 @@ struct mrq_response { #define MRQ_PING 0U #define MRQ_QUERY_TAG 1U -#define MRQ_MODULE_LOAD 4U -#define MRQ_MODULE_UNLOAD 5U -#define MRQ_TRACE_MODIFY 7U -#define MRQ_WRITE_TRACE 8U #define MRQ_THREADED_PING 9U -#define MRQ_MODULE_MAIL 11U #define MRQ_DEBUGFS 19U #define MRQ_RESET 20U #define MRQ_I2C 21U #define MRQ_CLK 22U #define MRQ_QUERY_ABI 23U -#define MRQ_PG_READ_STATE 25U -#define MRQ_PG_UPDATE_STATE 26U #define MRQ_THERMAL 27U #define MRQ_CPU_VHINT 28U #define MRQ_ABI_RATCHET 29U #define MRQ_EMC_DVFS_LATENCY 31U -#define MRQ_TRACE_ITER 64U #define MRQ_RINGBUF_CONSOLE 65U #define MRQ_PG 66U #define MRQ_CPU_NDIV_LIMITS 67U @@ -159,6 +332,40 @@ struct mrq_response { #define MRQ_FMON 72U #define MRQ_EC 73U #define MRQ_DEBUG 75U +#define MRQ_EMC_DVFS_EMCHUB 76U +#define MRQ_BWMGR 77U +#define MRQ_ISO_CLIENT 78U +#define MRQ_EMC_DISP_RFL 79U +#define MRQ_TELEMETRY 80U +#define MRQ_PWR_LIMIT 81U +#define MRQ_GEARS 82U +#define MRQ_BWMGR_INT 83U +#define MRQ_OC_STATUS 84U + +/** @cond DEPRECATED */ +#define MRQ_RESERVED_2 2U +#define MRQ_RESERVED_3 3U +#define MRQ_RESERVED_4 4U +#define MRQ_RESERVED_5 5U +#define MRQ_RESERVED_6 6U +#define MRQ_RESERVED_7 7U +#define MRQ_RESERVED_8 8U +#define MRQ_RESERVED_10 10U +#define MRQ_RESERVED_11 11U +#define MRQ_RESERVED_12 12U +#define MRQ_RESERVED_13 13U +#define MRQ_RESERVED_14 14U +#define MRQ_RESERVED_15 15U +#define MRQ_RESERVED_16 16U +#define MRQ_RESERVED_17 17U +#define MRQ_RESERVED_18 18U +#define MRQ_RESERVED_24 24U +#define MRQ_RESERVED_25 25U +#define MRQ_RESERVED_26 26U +#define MRQ_RESERVED_30 30U +#define MRQ_RESERVED_64 64U +#define MRQ_RESERVED_74 74U +/** @endcond DEPRECATED */ /** @} */ @@ -167,7 +374,7 @@ struct mrq_response { * @brief Maximum MRQ code to be sent by CPU software to * BPMP. Subject to change in future */ -#define MAX_CPU_MRQ_ID 75U +#define MAX_CPU_MRQ_ID 84U /** * @addtogroup MRQ_Payloads @@ -183,8 +390,11 @@ struct mrq_response { * @defgroup ABI_info ABI Info * @defgroup Powergating Power Gating * @defgroup Thermal Thermal + * @defgroup OC_status OC status * @defgroup Vhint CPU Voltage hint * @defgroup EMC EMC + * @defgroup BWMGR BWMGR + * @defgroup ISO_CLIENT ISO_CLIENT * @defgroup CPU NDIV Limits * @defgroup RingbufConsole Ring Buffer Console * @defgroup Strap Straps @@ -192,8 +402,11 @@ struct mrq_response { * @defgroup CC3 Auto-CC3 * @defgroup FMON FMON * @defgroup EC EC - * @defgroup Fbvolt_status Fuse Burn Voltage Status - * @} + * @defgroup Telemetry Telemetry + * @defgroup Pwrlimit PWR_LIMIT + * @defgroup Gears Gears + * @defgroup BWMGR_INT Bandwidth Manager Integrated + * @} MRQ_Payloads */ /** @@ -304,190 +517,6 @@ struct mrq_query_fw_tag_response { uint8_t tag[32]; } BPMP_ABI_PACKED; -/** - * @ingroup MRQ_Codes - * @def MRQ_MODULE_LOAD - * @brief Dynamically load a BPMP code module - * - * * Platforms: T210, T210B01, T186 - * @cond (bpmp_t210 || bpmp_t210b01 || bpmp_t186) - * * Initiators: CCPLEX - * * Targets: BPMP - * * Request Payload: @ref mrq_module_load_request - * * Response Payload: @ref mrq_module_load_response - * - * @note This MRQ is disabled on production systems - * - */ - -/** - * @ingroup Module - * @brief Request with #MRQ_MODULE_LOAD - * - * Used by #MRQ_MODULE_LOAD calls to ask the recipient to dynamically - * load the code located at #phys_addr and having size #size - * bytes. #phys_addr is treated as a void pointer. - * - * The recipient copies the code from #phys_addr to locally allocated - * memory prior to responding to this message. - * - * @todo document the module header format - * - * The sender is responsible for ensuring that the code is mapped in - * the recipient's address map. - * - */ -struct mrq_module_load_request { - /** @brief Base address of the code to load */ - uint32_t phys_addr; - /** @brief Size in bytes of code to load */ - uint32_t size; -} BPMP_ABI_PACKED; - -/** - * @ingroup Module - * @brief Response to #MRQ_MODULE_LOAD - * - * @todo document mrq_response::err - */ -struct mrq_module_load_response { - /** @brief Handle to the loaded module */ - uint32_t base; -} BPMP_ABI_PACKED; -/** @endcond*/ - -/** - * @ingroup MRQ_Codes - * @def MRQ_MODULE_UNLOAD - * @brief Unload a previously loaded code module - * - * * Platforms: T210, T210B01, T186 - * @cond (bpmp_t210 || bpmp_t210b01 || bpmp_t186) - * * Initiators: CCPLEX - * * Targets: BPMP - * * Request Payload: @ref mrq_module_unload_request - * * Response Payload: N/A - * - * @note This MRQ is disabled on production systems - */ - -/** - * @ingroup Module - * @brief Request with #MRQ_MODULE_UNLOAD - * - * Used by #MRQ_MODULE_UNLOAD calls to request that a previously loaded - * module be unloaded. - */ -struct mrq_module_unload_request { - /** @brief Handle of the module to unload */ - uint32_t base; -} BPMP_ABI_PACKED; -/** @endcond*/ - -/** - * @ingroup MRQ_Codes - * @def MRQ_TRACE_MODIFY - * @brief Modify the set of enabled trace events - * - * @deprecated - * - * * Platforms: All - * * Initiators: CCPLEX - * * Targets: BPMP - * * Request Payload: @ref mrq_trace_modify_request - * * Response Payload: @ref mrq_trace_modify_response - * - * @note This MRQ is disabled on production systems - */ - -/** - * @ingroup Trace - * @brief Request with #MRQ_TRACE_MODIFY - * - * Used by %MRQ_TRACE_MODIFY calls to enable or disable specify trace - * events. #set takes precedence for any bit set in both #set and - * #clr. - */ -struct mrq_trace_modify_request { - /** @brief Bit mask of trace events to disable */ - uint32_t clr; - /** @brief Bit mask of trace events to enable */ - uint32_t set; -} BPMP_ABI_PACKED; - -/** - * @ingroup Trace - * @brief Response to #MRQ_TRACE_MODIFY - * - * Sent in repsonse to an #MRQ_TRACE_MODIFY message. #mask reflects the - * state of which events are enabled after the recipient acted on the - * message. - * - */ -struct mrq_trace_modify_response { - /** @brief Bit mask of trace event enable states */ - uint32_t mask; -} BPMP_ABI_PACKED; - -/** - * @ingroup MRQ_Codes - * @def MRQ_WRITE_TRACE - * @brief Write trace data to a buffer - * - * @deprecated - * - * * Platforms: All - * * Initiators: CCPLEX - * * Targets: BPMP - * * Request Payload: @ref mrq_write_trace_request - * * Response Payload: @ref mrq_write_trace_response - * - * mrq_response::err depends on the @ref mrq_write_trace_request field - * values. err is -#BPMP_EINVAL if size is zero or area is NULL or - * area is in an illegal range. A positive value for err indicates the - * number of bytes written to area. - * - * @note This MRQ is disabled on production systems - */ - -/** - * @ingroup Trace - * @brief Request with #MRQ_WRITE_TRACE - * - * Used by MRQ_WRITE_TRACE calls to ask the recipient to copy trace - * data from the recipient's local buffer to the output buffer. #area - * is treated as a byte-aligned pointer in the recipient's address - * space. - * - * The sender is responsible for ensuring that the output - * buffer is mapped in the recipient's address map. The recipient is - * responsible for protecting its own code and data from accidental - * overwrites. - */ -struct mrq_write_trace_request { - /** @brief Base address of output buffer */ - uint32_t area; - /** @brief Size in bytes of the output buffer */ - uint32_t size; -} BPMP_ABI_PACKED; - -/** - * @ingroup Trace - * @brief Response to #MRQ_WRITE_TRACE - * - * Once this response is sent, the respondent will not access the - * output buffer further. - */ -struct mrq_write_trace_response { - /** - * @brief Flag whether more data remains in local buffer - * - * Value is 1 if the entire local trace buffer has been - * drained to the outputbuffer. Value is 0 otherwise. - */ - uint32_t eof; -} BPMP_ABI_PACKED; - /** @private */ struct mrq_threaded_ping_request { uint32_t challenge; @@ -500,50 +529,6 @@ struct mrq_threaded_ping_response { /** * @ingroup MRQ_Codes - * @def MRQ_MODULE_MAIL - * @brief Send a message to a loadable module - * - * * Platforms: T210, T210B01, T186 - * @cond (bpmp_t210 || bpmp_t210b01 || bpmp_t186) - * * Initiators: Any - * * Targets: BPMP - * * Request Payload: @ref mrq_module_mail_request - * * Response Payload: @ref mrq_module_mail_response - * - * @note This MRQ is disabled on production systems - */ - -/** - * @ingroup Module - * @brief Request with #MRQ_MODULE_MAIL - */ -struct mrq_module_mail_request { - /** @brief Handle to the previously loaded module */ - uint32_t base; - /** @brief Module-specific mail payload - * - * The length of data[ ] is unknown to the BPMP core firmware - * but it is limited to the size of an IPC message. - */ - uint8_t data[BPMP_ABI_EMPTY_ARRAY]; -} BPMP_ABI_PACKED; - -/** - * @ingroup Module - * @brief Response to #MRQ_MODULE_MAIL - */ -struct mrq_module_mail_response { - /** @brief Module-specific mail payload - * - * The length of data[ ] is unknown to the BPMP core firmware - * but it is limited to the size of an IPC message. - */ - uint8_t data[BPMP_ABI_EMPTY_ARRAY]; -} BPMP_ABI_PACKED; -/** @endcond */ - -/** - * @ingroup MRQ_Codes * @def MRQ_DEBUGFS * @brief Interact with BPMP's debugfs file nodes * @@ -686,7 +671,7 @@ struct mrq_debugfs_response { #define DEBUGFS_S_ISDIR (1 << 9) #define DEBUGFS_S_IRUSR (1 << 8) #define DEBUGFS_S_IWUSR (1 << 7) -/** @} */ +/** @} Debugfs */ /** * @ingroup MRQ_Codes @@ -970,7 +955,7 @@ struct mrq_reset_response { } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ +/** @} Reset */ /** * @ingroup MRQ_Codes @@ -1032,7 +1017,17 @@ struct serial_i2c_request { * @brief Trigger one or more i2c transactions */ struct cmd_i2c_xfer_request { - /** @brief Valid bus number from @ref bpmp_i2c_ids*/ + /** + * @brief Tegra PWR_I2C bus identifier + * + * @cond (bpmp_t234 || bpmp_t239 || bpmp_t194) + * Must be set to 5. + * @endcond (bpmp_t234 || bpmp_t239 || bpmp_t194) + * @cond bpmp_th500 + * Must be set to 1. + * @endcond bpmp_th500 + * + */ uint32_t bus_id; /** @brief Count of valid bytes in #data_buf*/ @@ -1084,7 +1079,7 @@ struct mrq_i2c_response { struct cmd_i2c_xfer_response xfer; } BPMP_ABI_PACKED; -/** @} */ +/** @} I2C */ /** * @ingroup MRQ_Codes @@ -1109,6 +1104,13 @@ enum { CMD_CLK_IS_ENABLED = 6, CMD_CLK_ENABLE = 7, CMD_CLK_DISABLE = 8, +/** @cond DEPRECATED */ + CMD_CLK_PROPERTIES = 9, + CMD_CLK_POSSIBLE_PARENTS = 10, + CMD_CLK_NUM_POSSIBLE_PARENTS = 11, + CMD_CLK_GET_POSSIBLE_PARENT = 12, + CMD_CLK_RESET_REFCOUNTS = 13, +/** @endcond DEPRECATED */ CMD_CLK_GET_ALL_INFO = 14, CMD_CLK_GET_MAX_CLK_ID = 15, CMD_CLK_GET_FMAX_AT_VMIN = 16, @@ -1119,6 +1121,21 @@ enum { #define BPMP_CLK_HAS_SET_RATE (1U << 1U) #define BPMP_CLK_IS_ROOT (1U << 2U) #define BPMP_CLK_IS_VAR_ROOT (1U << 3U) +/** + * @brief Protection against rate and parent changes + * + * #MRQ_CLK command #CMD_CLK_SET_RATE or #MRQ_CLK command #CMD_CLK_SET_PARENT will return + * -#BPMP_EACCES. + */ +#define BPMP_CLK_RATE_PARENT_CHANGE_DENIED (1U << 30) + +/** + * @brief Protection against state changes + * + * #MRQ_CLK command #CMD_CLK_ENABLE or #MRQ_CLK command #CMD_CLK_DISABLE will return + * -#BPMP_EACCES. + */ +#define BPMP_CLK_STATE_CHANGE_DENIED (1U << 31) #define MRQ_CLK_NAME_MAXLEN 40U #define MRQ_CLK_MAX_PARENTS 16U @@ -1177,7 +1194,7 @@ struct cmd_clk_is_enabled_request { */ struct cmd_clk_is_enabled_response { /** - * @brief The state of the clock that has been succesfully + * @brief The state of the clock that has been successfully * requested with CMD_CLK_ENABLE or CMD_CLK_DISABLE by the * master invoking the command earlier. * @@ -1210,6 +1227,46 @@ struct cmd_clk_disable_response { BPMP_ABI_EMPTY } BPMP_ABI_PACKED; +/** @cond DEPRECATED */ +/** @private */ +struct cmd_clk_properties_request { + BPMP_ABI_EMPTY +} BPMP_ABI_PACKED; + +/** @todo flags need to be spelled out here */ +struct cmd_clk_properties_response { + uint32_t flags; +} BPMP_ABI_PACKED; + +/** @private */ +struct cmd_clk_possible_parents_request { + BPMP_ABI_EMPTY +} BPMP_ABI_PACKED; + +struct cmd_clk_possible_parents_response { + uint8_t num_parents; + uint8_t reserved[3]; + uint32_t parent_id[MRQ_CLK_MAX_PARENTS]; +} BPMP_ABI_PACKED; + +/** @private */ +struct cmd_clk_num_possible_parents_request { + BPMP_ABI_EMPTY +} BPMP_ABI_PACKED; + +struct cmd_clk_num_possible_parents_response { + uint8_t num_parents; +} BPMP_ABI_PACKED; + +struct cmd_clk_get_possible_parent_request { + uint8_t parent_idx; +} BPMP_ABI_PACKED; + +struct cmd_clk_get_possible_parent_response { + uint32_t parent_id; +} BPMP_ABI_PACKED; +/** @endcond DEPRECATED */ + /** @private */ struct cmd_clk_get_all_info_request { BPMP_ABI_EMPTY @@ -1241,6 +1298,7 @@ struct cmd_clk_get_fmax_at_vmin_response { int64_t rate; } BPMP_ABI_PACKED; + /** * @ingroup Clocks * @brief Request with #MRQ_CLK @@ -1267,6 +1325,17 @@ struct cmd_clk_get_fmax_at_vmin_response { * */ +/** @cond DEPRECATED + * + * Older versions of firmware also supported following sub-commands: + * |CMD_CLK_PROPERTIES |- | + * |CMD_CLK_POSSIBLE_PARENTS |- | + * |CMD_CLK_NUM_POSSIBLE_PARENTS|- | + * |CMD_CLK_GET_POSSIBLE_PARENT |clk_get_possible_parent| + * |CMD_CLK_RESET_REFCOUNTS |- | + * + * @endcond DEPRECATED */ + struct mrq_clk_request { /** @brief Sub-command and clock id concatenated to 32-bit word. * - bits[31..24] is the sub-cmd. @@ -1288,6 +1357,15 @@ struct mrq_clk_request { struct cmd_clk_disable_request clk_disable; /** @private */ struct cmd_clk_is_enabled_request clk_is_enabled; + /** @cond DEPRECATED */ + /** @private */ + struct cmd_clk_properties_request clk_properties; + /** @private */ + struct cmd_clk_possible_parents_request clk_possible_parents; + /** @private */ + struct cmd_clk_num_possible_parents_request clk_num_possible_parents; + struct cmd_clk_get_possible_parent_request clk_get_possible_parent; + /** @endcond DEPRECATED */ /** @private */ struct cmd_clk_get_all_info_request clk_get_all_info; /** @private */ @@ -1321,6 +1399,17 @@ struct mrq_clk_request { * */ +/** @cond DEPRECATED + * + * Older versions of firmware also supported following sub-commands: + * |CMD_CLK_PROPERTIES |clk_properties | + * |CMD_CLK_POSSIBLE_PARENTS |clk_possible_parents | + * |CMD_CLK_NUM_POSSIBLE_PARENTS|clk_num_possible_parents| + * |CMD_CLK_GET_POSSIBLE_PARENT |clk_get_possible_parents| + * |CMD_CLK_RESET_REFCOUNTS |- | + * + * @endcond DEPRECATED */ + struct mrq_clk_response { union { struct cmd_clk_get_rate_response clk_get_rate; @@ -1333,13 +1422,19 @@ struct mrq_clk_response { /** @private */ struct cmd_clk_disable_response clk_disable; struct cmd_clk_is_enabled_response clk_is_enabled; + /** @cond DEPRECATED */ + struct cmd_clk_properties_response clk_properties; + struct cmd_clk_possible_parents_response clk_possible_parents; + struct cmd_clk_num_possible_parents_response clk_num_possible_parents; + struct cmd_clk_get_possible_parent_response clk_get_possible_parent; + /** @endcond DEPRECATED */ struct cmd_clk_get_all_info_response clk_get_all_info; struct cmd_clk_get_max_clk_id_response clk_get_max_clk_id; struct cmd_clk_get_fmax_at_vmin_response clk_get_fmax_at_vmin; } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ +/** @} Clocks */ /** * @ingroup MRQ_Codes @@ -1378,107 +1473,20 @@ struct mrq_query_abi_response { } BPMP_ABI_PACKED; /** - * @ingroup MRQ_Codes - * @def MRQ_PG_READ_STATE - * @brief Read the power-gating state of a partition * - * * Platforms: T186 - * @cond bpmp_t186 - * * Initiators: Any - * * Targets: BPMP - * * Request Payload: @ref mrq_pg_read_state_request - * * Response Payload: @ref mrq_pg_read_state_response - */ - -/** - * @ingroup Powergating - * @brief Request with #MRQ_PG_READ_STATE - * - * Used by MRQ_PG_READ_STATE call to read the current state of a - * partition. - */ -struct mrq_pg_read_state_request { - /** @brief ID of partition */ - uint32_t partition_id; -} BPMP_ABI_PACKED; - -/** - * @ingroup Powergating - * @brief Response to MRQ_PG_READ_STATE - * @todo define possible errors. - */ -struct mrq_pg_read_state_response { - /** @brief Read as don't care */ - uint32_t sram_state; - /** @brief State of power partition - * * 0 : off - * * 1 : on - */ - uint32_t logic_state; -} BPMP_ABI_PACKED; -/** @endcond*/ -/** @} */ - -/** - * @ingroup MRQ_Codes - * @def MRQ_PG_UPDATE_STATE - * @brief Modify the power-gating state of a partition. In contrast to - * MRQ_PG calls, the operations that change state (on/off) of power - * partition are reference counted. - * - * * Platforms: T186 - * @cond bpmp_t186 - * * Initiators: Any - * * Targets: BPMP - * * Request Payload: @ref mrq_pg_update_state_request - * * Response Payload: N/A - */ - -/** - * @ingroup Powergating - * @brief Request with mrq_pg_update_state_request - * - * Used by #MRQ_PG_UPDATE_STATE call to request BPMP to change the - * state of a power partition #partition_id. - */ -struct mrq_pg_update_state_request { - /** @brief ID of partition */ - uint32_t partition_id; - /** @brief Secondary control of power partition - * @details Ignored by many versions of the BPMP - * firmware. For maximum compatibility, set the value - * according to @ref logic_state - * * 0x1: power ON partition (@ref logic_state == 0x3) - * * 0x3: power OFF partition (@ref logic_state == 0x1) - */ - uint32_t sram_state; - /** @brief Controls state of power partition, legal values are - * * 0x1 : power OFF partition - * * 0x3 : power ON partition - */ - uint32_t logic_state; - /** @brief Change state of clocks of the power partition, legal values - * * 0x0 : do not change clock state - * * 0x1 : disable partition clocks (only applicable when - * @ref logic_state == 0x1) - * * 0x3 : enable partition clocks (only applicable when - * @ref logic_state == 0x3) - */ - uint32_t clock_state; -} BPMP_ABI_PACKED; -/** @endcond*/ - -/** * @ingroup MRQ_Codes * @def MRQ_PG * @brief Control power-gating state of a partition. In contrast to * MRQ_PG_UPDATE_STATE, operations that change the power partition * state are NOT reference counted * - * @note BPMP-FW forcefully turns off some partitions as part of SC7 entry - * because their state cannot be adequately restored on exit. Therefore, - * it is recommended to power off all domains via MRQ_PG prior to SC7 entry. + * @cond (bpmp_t194 || bpmp_t186) + * @note On T194 and earlier BPMP-FW forcefully turns off some partitions as + * part of SC7 entry because their state cannot be adequately restored on exit. + * Therefore, it is recommended to power off all domains via MRQ_PG prior to SC7 + * entry. * See @ref bpmp_pdomain_ids for further detail. + * @endcond (bpmp_t194 || bpmp_t186) * * * Platforms: T186, T194 * * Initiators: Any @@ -1643,7 +1651,7 @@ struct mrq_pg_response { } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ +/** @} Powergating */ /** * @ingroup MRQ_Codes @@ -1889,7 +1897,44 @@ union mrq_thermal_bpmp_to_host_response { struct cmd_thermal_get_thermtrip_response get_thermtrip; struct cmd_thermal_get_num_zones_response get_num_zones; } BPMP_ABI_PACKED; -/** @} */ + +/** @} Thermal */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_OC_STATUS + * @brief Query over current status + * + * * Platforms: T234 + * @cond bpmp_t234 + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: N/A + * * Response Payload: @ref mrq_oc_status_response + * + * @addtogroup OC_status + * @{ + */ + +#define OC_STATUS_MAX_SIZE 24U + +/* + * @brief Response to #MRQ_OC_STATUS + * + * throt_en: Value for each OC alarm where zero signifies throttle is + * disabled, and non-zero throttle is enabled. + * event_cnt: Total number of OC events for each OC alarm. + * + * mrq_response::err is 0 if the operation was successful and + * -#BPMP_ENODEV otherwise. + */ +struct mrq_oc_status_response { + uint8_t throt_en[OC_STATUS_MAX_SIZE]; + uint32_t event_cnt[OC_STATUS_MAX_SIZE]; +} BPMP_ABI_PACKED; + +/** @} OC_status */ +/** @endcond bpmp_t234 */ /** * @ingroup MRQ_Codes @@ -1948,8 +1993,9 @@ struct cpu_vhint_data { /** reserved for future use */ uint16_t reserved[328]; } BPMP_ABI_PACKED; -/** @endcond */ -/** @} */ + +/** @} Vhint */ +/** @endcond bpmp_t186 */ /** * @ingroup MRQ_Codes @@ -2016,14 +2062,15 @@ struct mrq_abi_ratchet_response { /** @brief BPMP's ratchet value */ uint16_t ratchet; }; -/** @} */ + +/** @} ABI_info */ /** * @ingroup MRQ_Codes * @def MRQ_EMC_DVFS_LATENCY * @brief Query frequency dependent EMC DVFS latency * - * * Platforms: T186, T194 + * * Platforms: T186, T194, T234 * * Initiators: CCPLEX * * Targets: BPMP * * Request Payload: N/A @@ -2053,7 +2100,543 @@ struct mrq_emc_dvfs_latency_response { struct emc_dvfs_latency pairs[EMC_DVFS_LATENCY_MAX_SIZE]; } BPMP_ABI_PACKED; -/** @} */ +/** @} EMC */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_EMC_DVFS_EMCHUB + * @brief Query EMC HUB frequencies + * + * * Platforms: T234 onwards + * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500) + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: N/A + * * Response Payload: @ref mrq_emc_dvfs_emchub_response + * @addtogroup EMC + * @{ + */ + +/** + * @brief Used by @ref mrq_emc_dvfs_emchub_response + */ +struct emc_dvfs_emchub { + /** @brief EMC DVFS node frequency in kHz */ + uint32_t freq; + /** @brief EMC HUB frequency in kHz */ + uint32_t hub_freq; +} BPMP_ABI_PACKED; + +#define EMC_DVFS_EMCHUB_MAX_SIZE EMC_DVFS_LATENCY_MAX_SIZE +/** + * @brief Response to #MRQ_EMC_DVFS_EMCHUB + */ +struct mrq_emc_dvfs_emchub_response { + /** @brief The number valid entries in #pairs */ + uint32_t num_pairs; + /** @brief EMC DVFS node <frequency, hub frequency> information */ + struct emc_dvfs_emchub pairs[EMC_DVFS_EMCHUB_MAX_SIZE]; +} BPMP_ABI_PACKED; + +/** @} EMC */ +/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_EMC_DISP_RFL + * @brief Set EMC display RFL handshake mode of operations + * + * * Platforms: T234 onwards + * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500) + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: @ref mrq_emc_disp_rfl_request + * * Response Payload: N/A + * + * @addtogroup EMC + * @{ + */ + +enum mrq_emc_disp_rfl_mode { + /** @brief EMC display RFL handshake disabled */ + EMC_DISP_RFL_MODE_DISABLED = 0, + /** @brief EMC display RFL handshake enabled */ + EMC_DISP_RFL_MODE_ENABLED = 1, +}; + +/** + * @ingroup EMC + * @brief Request with #MRQ_EMC_DISP_RFL + * + * Used by the sender of an #MRQ_EMC_DISP_RFL message to + * request the mode of EMC display RFL handshake. + * + * mrq_response::err is + * * 0: RFL mode is set successfully + * * -#BPMP_EINVAL: invalid mode requested + * * -#BPMP_ENOSYS: RFL handshake is not supported + * * -#BPMP_EACCES: Permission denied + * * -#BPMP_ENODEV: if disp rfl mrq is not supported by BPMP-FW + */ +struct mrq_emc_disp_rfl_request { + /** @brief EMC display RFL mode (@ref mrq_emc_disp_rfl_mode) */ + uint32_t mode; +} BPMP_ABI_PACKED; + +/** @} EMC */ +/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_BWMGR + * @brief bwmgr requests + * + * * Platforms: T234 onwards + * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500) + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: @ref mrq_bwmgr_request + * * Response Payload: @ref mrq_bwmgr_response + * + * @addtogroup BWMGR + * + * @{ + */ + +enum mrq_bwmgr_cmd { + /** + * @brief Check whether the BPMP driver supports the specified + * request type + * + * mrq_response::err is 0 if the specified request is + * supported and -#BPMP_ENODEV otherwise. + */ + CMD_BWMGR_QUERY_ABI = 0, + + /** + * @brief Determine dram rate to satisfy iso/niso bw requests + * + * mrq_response::err is + * * 0: calc_rate succeeded. + * * -#BPMP_EINVAL: Invalid request parameters. + * * -#BPMP_ENOTSUP: Requested bw is not available. + */ + CMD_BWMGR_CALC_RATE = 1 +}; + +/* + * request data for request type CMD_BWMGR_QUERY_ABI + * + * type: Request type for which to check existence. + */ +struct cmd_bwmgr_query_abi_request { + uint32_t type; +} BPMP_ABI_PACKED; + +/** + * @brief Used by @ref cmd_bwmgr_calc_rate_request + */ +struct iso_req { + /* @brief bwmgr client ID @ref bpmp_bwmgr_ids */ + uint32_t id; + /* @brief bw in kBps requested by client */ + uint32_t iso_bw; +} BPMP_ABI_PACKED; + +#define MAX_ISO_CLIENTS 13U +/* + * request data for request type CMD_BWMGR_CALC_RATE + */ +struct cmd_bwmgr_calc_rate_request { + /* @brief total bw in kBps requested by all niso clients */ + uint32_t sum_niso_bw; + /* @brief The number of iso clients */ + uint32_t num_iso_clients; + /* @brief iso_req <id, iso_bw> information */ + struct iso_req isobw_reqs[MAX_ISO_CLIENTS]; +} BPMP_ABI_PACKED; + +/* + * response data for request type CMD_BWMGR_CALC_RATE + * + * iso_rate_min: min dram data clk rate in kHz to satisfy all iso bw reqs + * total_rate_min: min dram data clk rate in kHz to satisfy all bw reqs + */ +struct cmd_bwmgr_calc_rate_response { + uint32_t iso_rate_min; + uint32_t total_rate_min; +} BPMP_ABI_PACKED; + +/* + * @brief Request with #MRQ_BWMGR + * + * + * |sub-command |payload | + * |----------------------------|------------------------------| + * |CMD_BWMGR_QUERY_ABI | cmd_bwmgr_query_abi_request | + * |CMD_BWMGR_CALC_RATE | cmd_bwmgr_calc_rate_request | + * + */ +struct mrq_bwmgr_request { + uint32_t cmd; + union { + struct cmd_bwmgr_query_abi_request query_abi; + struct cmd_bwmgr_calc_rate_request bwmgr_rate_req; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/* + * @brief Response to MRQ_BWMGR + * + * |sub-command |payload | + * |----------------------------|------------------------------| + * |CMD_BWMGR_CALC_RATE | cmd_bwmgr_calc_rate_response | + */ +struct mrq_bwmgr_response { + union { + struct cmd_bwmgr_calc_rate_response bwmgr_rate_resp; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** @} BWMGR */ +/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_BWMGR_INT + * @brief bpmp-integrated bwmgr requests + * + * * Platforms: T234 onwards + * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500) + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: @ref mrq_bwmgr_int_request + * * Response Payload: @ref mrq_bwmgr_int_response + * + * @addtogroup BWMGR_INT + * @{ + */ + +enum mrq_bwmgr_int_cmd { + /** + * @brief Check whether the BPMP-FW supports the specified + * request type + * + * mrq_response::err is 0 if the specified request is + * supported and -#BPMP_ENODEV otherwise. + */ + CMD_BWMGR_INT_QUERY_ABI = 1, + + /** + * @brief Determine and set dram rate to satisfy iso/niso bw request + * + * mrq_response::err is + * * 0: request succeeded. + * * -#BPMP_EINVAL: Invalid request parameters. + * set_frequency in @ref cmd_bwmgr_int_calc_and_set_response + * will not be set. + * * -#BPMP_ENOTSUP: Requested bw is not available. + * set_frequency in @ref cmd_bwmgr_int_calc_and_set_response + * will be current dram-clk rate. + */ + CMD_BWMGR_INT_CALC_AND_SET = 2, + + /** + * @brief Set a max DRAM frequency for the bandwidth-manager + * + * mrq_response::err is + * * 0: request succeeded. + * * -#BPMP_ENOTSUP: Requested cap frequency is not possible. + */ + CMD_BWMGR_INT_CAP_SET = 3 +}; + +/* + * request structure for request type CMD_BWMGR_QUERY_ABI + * + * type: Request type for which to check existence. + */ +struct cmd_bwmgr_int_query_abi_request { + /* @brief request type determined by @ref mrq_bwmgr_int_cmd */ + uint32_t type; +} BPMP_ABI_PACKED; + +/** + * @defgroup bwmgr_int_unit_type BWMGR_INT floor unit-types + * @addtogroup bwmgr_int_unit_type + * @{ + */ +/** @brief kilobytes per second unit-type */ +#define BWMGR_INT_UNIT_KBPS 0U +/** @brief kilohertz unit-type */ +#define BWMGR_INT_UNIT_KHZ 1U + +/** @} bwmgr_int_unit_type */ + +/* + * request data for request type CMD_BWMGR_INT_CALC_AND_SET + */ +struct cmd_bwmgr_int_calc_and_set_request { + /* @brief bwmgr client ID @ref bpmp_bwmgr_ids */ + uint32_t client_id; + /* @brief average niso bw usage in kBps requested by client. */ + uint32_t niso_bw; + /* + * @brief average iso bw usage in kBps requested by client. + * Value is ignored if client is niso. Determined by client_id. + */ + uint32_t iso_bw; + /* + * @brief memory clock floor requested by client. + * Unit determined by floor_unit. + */ + uint32_t mc_floor; + /* + * @brief toggle to determine the unit-type of floor value. + * See @ref bwmgr_int_unit_type definitions for unit-type mappings. + */ + uint8_t floor_unit; +} BPMP_ABI_PACKED; + +struct cmd_bwmgr_int_cap_set_request { + /* @brief requested cap frequency in Hz. */ + uint64_t rate; +} BPMP_ABI_PACKED; + +/* + * response data for request type CMD_BWMGR_CALC_AND_SET + */ +struct cmd_bwmgr_int_calc_and_set_response { + /* @brief current set memory clock frequency in Hz */ + uint64_t rate; +} BPMP_ABI_PACKED; + +/* + * @brief Request with #MRQ_BWMGR_INT + * + * + * |sub-command |payload | + * |----------------------------|-----------------------------------| + * |CMD_BWMGR_INT_QUERY_ABI | cmd_bwmgr_int_query_abi_request | + * |CMD_BWMGR_INT_CALC_AND_SET | cmd_bwmgr_int_calc_and_set_request| + * |CMD_BWMGR_INT_CAP_SET | cmd_bwmgr_int_cap_set_request | + * + */ +struct mrq_bwmgr_int_request { + uint32_t cmd; + union { + struct cmd_bwmgr_int_query_abi_request query_abi; + struct cmd_bwmgr_int_calc_and_set_request bwmgr_calc_set_req; + struct cmd_bwmgr_int_cap_set_request bwmgr_cap_set_req; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/* + * @brief Response to MRQ_BWMGR_INT + * + * |sub-command |payload | + * |----------------------------|---------------------------------------| + * |CMD_BWMGR_INT_CALC_AND_SET | cmd_bwmgr_int_calc_and_set_response | + */ +struct mrq_bwmgr_int_response { + union { + struct cmd_bwmgr_int_calc_and_set_response bwmgr_calc_set_resp; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** @} BWMGR_INT */ +/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_ISO_CLIENT + * @brief ISO client requests + * + * * Platforms: T234 onwards + * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500) + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: @ref mrq_iso_client_request + * * Response Payload: @ref mrq_iso_client_response + * + * @addtogroup ISO_CLIENT + * @{ + */ + +enum mrq_iso_client_cmd { + /** + * @brief Check whether the BPMP driver supports the specified + * request type + * + * mrq_response::err is 0 if the specified request is + * supported and -#BPMP_ENODEV otherwise. + */ + CMD_ISO_CLIENT_QUERY_ABI = 0, + + /* + * @brief check for legal LA for the iso client. Without programming + * LA MC registers, calculate and ensure that legal LA is possible for + * iso bw requested by the ISO client. + * + * mrq_response::err is + * * 0: check la succeeded. + * * -#BPMP_EINVAL: Invalid request parameters. + * * -#BPMP_EFAULT: Legal LA is not possible for client requested iso_bw + */ + CMD_ISO_CLIENT_CALCULATE_LA = 1, + + /* + * @brief set LA for the iso client. Calculate and program the LA/PTSA + * MC registers corresponding to the client making bw request + * + * mrq_response::err is + * * 0: set la succeeded. + * * -#BPMP_EINVAL: Invalid request parameters. + * * -#BPMP_EFAULT: Failed to calculate or program MC registers. + */ + CMD_ISO_CLIENT_SET_LA = 2, + + /* + * @brief Get max possible bw for iso client + * + * mrq_response::err is + * * 0: get_max_bw succeeded. + * * -#BPMP_EINVAL: Invalid request parameters. + */ + CMD_ISO_CLIENT_GET_MAX_BW = 3 +}; + +/* + * request data for request type CMD_ISO_CLIENT_QUERY_ABI + * + * type: Request type for which to check existence. + */ +struct cmd_iso_client_query_abi_request { + uint32_t type; +} BPMP_ABI_PACKED; + +/* + * request data for request type CMD_ISO_CLIENT_CALCULATE_LA + * + * id: client ID in @ref bpmp_bwmgr_ids + * bw: bw requested in kBps by client ID. + * init_bw_floor: initial dram_bw_floor in kBps passed by client ID. + * ISO client will perform mempool allocation and DVFS buffering based + * on this dram_bw_floor. + */ +struct cmd_iso_client_calculate_la_request { + uint32_t id; + uint32_t bw; + uint32_t init_bw_floor; +} BPMP_ABI_PACKED; + +/* + * request data for request type CMD_ISO_CLIENT_SET_LA + * + * id: client ID in @ref bpmp_bwmgr_ids + * bw: bw requested in kBps by client ID. + * final_bw_floor: final dram_bw_floor in kBps. + * Sometimes the initial dram_bw_floor passed by ISO client may need to be + * updated by considering higher dram freq's. This is the final dram_bw_floor + * used to calculate and program MC registers. + */ +struct cmd_iso_client_set_la_request { + uint32_t id; + uint32_t bw; + uint32_t final_bw_floor; +} BPMP_ABI_PACKED; + +/* + * request data for request type CMD_ISO_CLIENT_GET_MAX_BW + * + * id: client ID in @ref bpmp_bwmgr_ids + */ +struct cmd_iso_client_get_max_bw_request { + uint32_t id; +} BPMP_ABI_PACKED; + +/* + * response data for request type CMD_ISO_CLIENT_CALCULATE_LA + * + * la_rate_floor: minimum dram_rate_floor in kHz at which a legal la is possible + * iso_client_only_rate: Minimum dram freq in kHz required to satisfy this clients + * iso bw request, assuming all other iso clients are inactive + */ +struct cmd_iso_client_calculate_la_response { + uint32_t la_rate_floor; + uint32_t iso_client_only_rate; +} BPMP_ABI_PACKED; + +/** + * @brief Used by @ref cmd_iso_client_get_max_bw_response + */ +struct iso_max_bw { + /* @brief dram frequency in kHz */ + uint32_t freq; + /* @brief max possible iso-bw in kBps */ + uint32_t iso_bw; +} BPMP_ABI_PACKED; + +#define ISO_MAX_BW_MAX_SIZE 14U +/* + * response data for request type CMD_ISO_CLIENT_GET_MAX_BW + */ +struct cmd_iso_client_get_max_bw_response { + /* @brief The number valid entries in iso_max_bw pairs */ + uint32_t num_pairs; + /* @brief max ISOBW <dram freq, max bw> information */ + struct iso_max_bw pairs[ISO_MAX_BW_MAX_SIZE]; +} BPMP_ABI_PACKED; + +/** + * @brief Request with #MRQ_ISO_CLIENT + * + * Used by the sender of an #MRQ_ISO_CLIENT message. + * + * |sub-command |payload | + * |------------------------------------ |----------------------------------------| + * |CMD_ISO_CLIENT_QUERY_ABI |cmd_iso_client_query_abi_request | + * |CMD_ISO_CLIENT_CALCULATE_LA |cmd_iso_client_calculate_la_request | + * |CMD_ISO_CLIENT_SET_LA |cmd_iso_client_set_la_request | + * |CMD_ISO_CLIENT_GET_MAX_BW |cmd_iso_client_get_max_bw_request | + * + */ + +struct mrq_iso_client_request { + /* Type of request. Values listed in enum mrq_iso_client_cmd */ + uint32_t cmd; + union { + struct cmd_iso_client_query_abi_request query_abi; + struct cmd_iso_client_calculate_la_request calculate_la_req; + struct cmd_iso_client_set_la_request set_la_req; + struct cmd_iso_client_get_max_bw_request max_isobw_req; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** + * @brief Response to MRQ_ISO_CLIENT + * + * Each sub-command supported by @ref mrq_iso_client_request may return + * sub-command-specific data. Some do and some do not as indicated in + * the following table + * + * |sub-command |payload | + * |---------------------------- |------------------------------------| + * |CMD_ISO_CLIENT_CALCULATE_LA |cmd_iso_client_calculate_la_response| + * |CMD_ISO_CLIENT_SET_LA |N/A | + * |CMD_ISO_CLIENT_GET_MAX_BW |cmd_iso_client_get_max_bw_response | + * + */ + +struct mrq_iso_client_response { + union { + struct cmd_iso_client_calculate_la_response calculate_la_resp; + struct cmd_iso_client_get_max_bw_response max_isobw_resp; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** @} ISO_CLIENT */ +/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */ /** * @ingroup MRQ_Codes @@ -2061,7 +2644,7 @@ struct mrq_emc_dvfs_latency_response { * @brief CPU freq. limits in ndiv * * * Platforms: T194 onwards - * @cond bpmp_t194 + * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) * * Initiators: CCPLEX * * Targets: BPMP * * Request Payload: @ref mrq_cpu_ndiv_limits_request @@ -2094,15 +2677,15 @@ struct mrq_cpu_ndiv_limits_response { uint16_t ndiv_min; } BPMP_ABI_PACKED; -/** @} */ -/** @endcond */ +/** @} CPU */ +/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */ /** * @ingroup MRQ_Codes * @def MRQ_CPU_AUTO_CC3 * @brief Query CPU cluster auto-CC3 configuration * - * * Platforms: T194 onwards + * * Platforms: T194 * @cond bpmp_t194 * * Initiators: CCPLEX * * Targets: BPMP @@ -2140,40 +2723,8 @@ struct mrq_cpu_auto_cc3_response { uint32_t auto_cc3_config; } BPMP_ABI_PACKED; -/** @} */ -/** @endcond */ - -/** - * @ingroup MRQ_Codes - * @def MRQ_TRACE_ITER - * @brief Manage the trace iterator - * - * @deprecated - * - * * Platforms: All - * * Initiators: CCPLEX - * * Targets: BPMP - * * Request Payload: N/A - * * Response Payload: @ref mrq_trace_iter_request - * @addtogroup Trace - * @{ - */ -enum { - /** @brief (re)start the tracing now. Ignore older events */ - TRACE_ITER_INIT = 0, - /** @brief Clobber all events in the trace buffer */ - TRACE_ITER_CLEAN = 1 -}; - -/** - * @brief Request with #MRQ_TRACE_ITER - */ -struct mrq_trace_iter_request { - /** @brief TRACE_ITER_INIT or TRACE_ITER_CLEAN */ - uint32_t cmd; -} BPMP_ABI_PACKED; - -/** @} */ +/** @} CC3 */ +/** @endcond bpmp_t194 */ /** * @ingroup MRQ_Codes @@ -2351,7 +2902,8 @@ union mrq_ringbuf_console_bpmp_to_host_response { struct cmd_ringbuf_console_write_resp write; struct cmd_ringbuf_console_get_fifo_resp get_fifo; } BPMP_ABI_PACKED; -/** @} */ + +/** @} RingbufConsole */ /** * @ingroup MRQ_Codes @@ -2359,7 +2911,7 @@ union mrq_ringbuf_console_bpmp_to_host_response { * @brief Set a strap value controlled by BPMP * * * Platforms: T194 onwards - * @cond bpmp_t194 + * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) * * Initiators: CCPLEX * * Targets: BPMP * * Request Payload: @ref mrq_strap_request @@ -2390,17 +2942,14 @@ enum mrq_strap_cmd { struct mrq_strap_request { /** @brief @ref mrq_strap_cmd */ uint32_t cmd; - /** @brief Strap ID from @ref Strap_Ids */ + /** @brief Strap ID from @ref Strap_Identifiers */ uint32_t id; /** @brief Desired value for strap (if cmd is #STRAP_SET) */ uint32_t value; } BPMP_ABI_PACKED; -/** - * @defgroup Strap_Ids Strap Identifiers - * @} - */ -/** @endcond */ +/** @} Strap */ +/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */ /** * @ingroup MRQ_Codes @@ -2408,7 +2957,7 @@ struct mrq_strap_request { * @brief Perform a UPHY operation * * * Platforms: T194 onwards - * @cond bpmp_t194 + * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) * * Initiators: CCPLEX * * Targets: BPMP * * Request Payload: @ref mrq_uphy_request @@ -2423,6 +2972,9 @@ enum { CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT = 3, CMD_UPHY_PCIE_CONTROLLER_STATE = 4, CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF = 5, + CMD_UPHY_DISPLAY_PORT_INIT = 6, + CMD_UPHY_DISPLAY_PORT_OFF = 7, + CMD_UPHY_XUSB_DYN_LANES_RESTORE = 8, CMD_UPHY_MAX, }; @@ -2445,28 +2997,41 @@ struct cmd_uphy_margin_status_response { } BPMP_ABI_PACKED; struct cmd_uphy_ep_controller_pll_init_request { - /** @brief EP controller number, valid: 0, 4, 5 */ + /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T239 valid: 0 */ uint8_t ep_controller; } BPMP_ABI_PACKED; struct cmd_uphy_pcie_controller_state_request { - /** @brief PCIE controller number, valid: 0, 1, 2, 3, 4 */ + /** @brief PCIE controller number, T194 valid: 0-4; T234 valid: 0-10; T239 valid: 0-3 */ uint8_t pcie_controller; uint8_t enable; } BPMP_ABI_PACKED; struct cmd_uphy_ep_controller_pll_off_request { - /** @brief EP controller number, valid: 0, 4, 5 */ + /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T239 valid: 0 */ uint8_t ep_controller; } BPMP_ABI_PACKED; +struct cmd_uphy_display_port_init_request { + /** @brief DisplayPort link rate, T239 valid: 1620, 2700, 5400, 8100, 2160, 2430, 3240, 4320, 6750 */ + uint16_t link_rate; + /** @brief 1: lane 0; 2: lane 1; 3: lane 0 and 1 */ + uint16_t lanes_bitmap; +} BPMP_ABI_PACKED; + +struct cmd_uphy_xusb_dyn_lanes_restore_request { + /** @brief 1: lane 0; 2: lane 1; 3: lane 0 and 1 */ + uint16_t lanes_bitmap; +} BPMP_ABI_PACKED; + /** * @ingroup UPHY * @brief Request with #MRQ_UPHY * - * Used by the sender of an #MRQ_UPHY message to control UPHY Lane RX margining. - * The uphy_request is split into several sub-commands. Some sub-commands - * require no additional data. Others have a sub-command specific payload + * Used by the sender of an #MRQ_UPHY message to control UPHY. + * The uphy_request is split into several sub-commands. CMD_UPHY_PCIE_LANE_MARGIN_STATUS + * requires no additional data. Others have a sub-command specific payload. Below table + * shows sub-commands with their corresponding payload data. * * |sub-command |payload | * |------------------------------------ |----------------------------------------| @@ -2475,6 +3040,9 @@ struct cmd_uphy_ep_controller_pll_off_request { * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |cmd_uphy_ep_controller_pll_init_request | * |CMD_UPHY_PCIE_CONTROLLER_STATE |cmd_uphy_pcie_controller_state_request | * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF |cmd_uphy_ep_controller_pll_off_request | + * |CMD_UPHY_PCIE_DISPLAY_PORT_INIT |cmd_uphy_display_port_init_request | + * |CMD_UPHY_PCIE_DISPLAY_PORT_OFF | | + * |CMD_UPHY_XUSB_DYN_LANES_RESTORE |cmd_uphy_xusb_dyn_lanes_restore_request | * */ @@ -2489,6 +3057,8 @@ struct mrq_uphy_request { struct cmd_uphy_ep_controller_pll_init_request ep_ctrlr_pll_init; struct cmd_uphy_pcie_controller_state_request controller_state; struct cmd_uphy_ep_controller_pll_off_request ep_ctrlr_pll_off; + struct cmd_uphy_display_port_init_request display_port_init; + struct cmd_uphy_xusb_dyn_lanes_restore_request xusb_dyn_lanes_restore; } BPMP_UNION_ANON; } BPMP_ABI_PACKED; @@ -2513,8 +3083,8 @@ struct mrq_uphy_response { } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ -/** @endcond */ +/** @} UPHY */ +/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */ /** * @ingroup MRQ_Codes @@ -2522,14 +3092,16 @@ struct mrq_uphy_response { * @brief Perform a frequency monitor configuration operations * * * Platforms: T194 onwards - * @cond bpmp_t194 + * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) * * Initiators: CCPLEX * * Targets: BPMP * * Request Payload: @ref mrq_fmon_request * * Response Payload: @ref mrq_fmon_response + * @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) * * @addtogroup FMON * @{ + * @cond (bpmp_t194 || bpmp_t234) */ enum { /** @@ -2538,6 +3110,20 @@ enum { * The monitored clock must be running for clamp to succeed. If * clamped, FMON configuration is preserved when clock rate * and/or state is changed. + * + * mrq_response::err is 0 if the operation was successful, or @n + * -#BPMP_EACCES: FMON access error @n + * -#BPMP_EBADCMD if subcommand is not supported @n + * -#BPMP_EBADSLT: clamp FMON on cluster with auto-CC3 enabled @n + * -#BPMP_EBUSY: fmon is already clamped at different rate @n + * -#BPMP_EFAULT: self-diagnostic error @n + * -#BPMP_EINVAL: invalid FMON configuration @n + * -#BPMP_EOPNOTSUPP: not in production mode @n + * -#BPMP_ENODEV: invalid clk_id @n + * -#BPMP_ENOENT: no calibration data, uninitialized @n + * -#BPMP_ENOTSUP: avfs config not set @n + * -#BPMP_ENOSYS: clamp FMON on cluster clock w/ no NAFLL @n + * -#BPMP_ETIMEDOUT: operation timed out @n */ CMD_FMON_GEAR_CLAMP = 1, /** @@ -2545,6 +3131,13 @@ enum { * * Allow FMON configuration to follow monitored clock rate * and/or state changes. + * + * mrq_response::err is 0 if the operation was successful, or @n + * -#BPMP_EBADCMD if subcommand is not supported @n + * -#BPMP_ENODEV: invalid clk_id @n + * -#BPMP_ENOENT: no calibration data, uninitialized @n + * -#BPMP_ENOTSUP: avfs config not set @n + * -#BPMP_EOPNOTSUPP: not in production mode @n */ CMD_FMON_GEAR_FREE = 2, /** @@ -2553,11 +3146,54 @@ enum { * * Inherently racy, since clamp state can be changed * concurrently. Useful for testing. + * + * mrq_response::err is 0 if the operation was successful, or @n + * -#BPMP_EBADCMD if subcommand is not supported @n + * -#BPMP_ENODEV: invalid clk_id @n + * -#BPMP_ENOENT: no calibration data, uninitialized @n + * -#BPMP_ENOTSUP: avfs config not set @n + * -#BPMP_EOPNOTSUPP: not in production mode @n */ CMD_FMON_GEAR_GET = 3, - CMD_FMON_NUM, + /** + * @brief Return current status of FMON faults detected by FMON + * h/w or s/w since last invocation of this command. + * Clears fault status. + * + * mrq_response::err is 0 if the operation was successful, or @n + * -#BPMP_EBADCMD if subcommand is not supported @n + * -#BPMP_EINVAL: invalid fault type @n + * -#BPMP_ENODEV: invalid clk_id @n + * -#BPMP_ENOENT: no calibration data, uninitialized @n + * -#BPMP_ENOTSUP: avfs config not set @n + * -#BPMP_EOPNOTSUPP: not in production mode @n + */ + CMD_FMON_FAULT_STS_GET = 4, }; +/** + * @cond DEPRECATED + * Kept for backward compatibility + */ +#define CMD_FMON_NUM 4 + +/** @endcond DEPRECATED */ + +/** + * @defgroup fmon_fault_type FMON fault type + * @addtogroup fmon_fault_type + * @{ + */ +/** @brief All detected FMON faults (h/w or s/w) */ +#define FMON_FAULT_TYPE_ALL 0U +/** @brief FMON faults detected by h/w */ +#define FMON_FAULT_TYPE_HW 1U +/** @brief FMON faults detected by s/w */ +#define FMON_FAULT_TYPE_SW 2U + +/** @} fmon_fault_type */ + + struct cmd_fmon_gear_clamp_request { int32_t unused; int64_t rate; @@ -2587,6 +3223,14 @@ struct cmd_fmon_gear_get_response { int64_t rate; } BPMP_ABI_PACKED; +struct cmd_fmon_fault_sts_get_request { + uint32_t fault_type; /**< @ref fmon_fault_type */ +} BPMP_ABI_PACKED; + +struct cmd_fmon_fault_sts_get_response { + uint32_t fault_sts; +} BPMP_ABI_PACKED; + /** * @ingroup FMON * @brief Request with #MRQ_FMON @@ -2601,9 +3245,9 @@ struct cmd_fmon_gear_get_response { * |CMD_FMON_GEAR_CLAMP |fmon_gear_clamp | * |CMD_FMON_GEAR_FREE |- | * |CMD_FMON_GEAR_GET |- | + * |CMD_FMON_FAULT_STS_GET |fmon_fault_sts_get | * */ - struct mrq_fmon_request { /** @brief Sub-command and clock id concatenated to 32-bit word. * - bits[31..24] is the sub-cmd. @@ -2618,6 +3262,7 @@ struct mrq_fmon_request { struct cmd_fmon_gear_free_request fmon_gear_free; /** @private */ struct cmd_fmon_gear_get_request fmon_gear_get; + struct cmd_fmon_fault_sts_get_request fmon_fault_sts_get; } BPMP_UNION_ANON; } BPMP_ABI_PACKED; @@ -2633,6 +3278,7 @@ struct mrq_fmon_request { * |CMD_FMON_GEAR_CLAMP |- | * |CMD_FMON_GEAR_FREE |- | * |CMD_FMON_GEAR_GET |fmon_gear_get | + * |CMD_FMON_FAULT_STS_GET |fmon_fault_sts_get | * */ @@ -2643,11 +3289,12 @@ struct mrq_fmon_response { /** @private */ struct cmd_fmon_gear_free_response fmon_gear_free; struct cmd_fmon_gear_get_response fmon_gear_get; + struct cmd_fmon_fault_sts_get_response fmon_fault_sts_get; } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ -/** @endcond */ +/** @endcond (bpmp_t194 || bpmp_t234) */ +/** @} FMON */ /** * @ingroup MRQ_Codes @@ -2655,7 +3302,7 @@ struct mrq_fmon_response { * @brief Provide status information on faults reported by Error * Collator (EC) to HSM. * - * * Platforms: T194 onwards + * * Platforms: T194 * @cond bpmp_t194 * * Initiators: CCPLEX * * Targets: BPMP @@ -2664,8 +3311,10 @@ struct mrq_fmon_response { * * @note This MRQ ABI is under construction, and subject to change * + * @endcond bpmp_t194 * @addtogroup EC * @{ + * @cond bpmp_t194 */ enum { /** @@ -2676,7 +3325,7 @@ enum { * -#BPMP_ENODEV if target EC is not owned by BPMP @n * -#BPMP_EACCES if target EC power domain is turned off @n * -#BPMP_EBADCMD if subcommand is not supported - * @endcond + * @endcond DEPRECATED */ CMD_EC_STATUS_GET = 1, /* deprecated */ @@ -2787,7 +3436,8 @@ enum ec_registers_group { #define EC_STATUS_FLAG_LAST_ERROR 0x0002U /** @brief EC latent error flag */ #define EC_STATUS_FLAG_LATENT_ERROR 0x0004U -/** @} */ + +/** @} bpmp_ec_status_flags */ /** * @defgroup bpmp_ec_desc_flags EC Descriptor Flags @@ -2798,7 +3448,8 @@ enum ec_registers_group { #define EC_DESC_FLAG_RESOLVED 0x0001U /** @brief EC descriptor failed to retrieve id flag */ #define EC_DESC_FLAG_NO_ID 0x0002U -/** @} */ + +/** @} bpmp_ec_desc_flags */ /** * |error type | fmon_clk_id values | @@ -2810,14 +3461,18 @@ struct ec_err_fmon_desc { uint16_t desc_flags; /** @brief FMON monitored clock id */ uint16_t fmon_clk_id; - /** @brief Bitmask of @ref bpmp_fmon_faults_flags */ + /** + * @brief Bitmask of fault flags + * + * @ref bpmp_fmon_faults_flags + */ uint32_t fmon_faults; /** @brief FMON faults access error */ int32_t fmon_access_error; } BPMP_ABI_PACKED; /** - * |error type | vmon_adc_id values | + * | error type | vmon_adc_id values | * |---------------------------------|---------------------------| * |@ref EC_ERR_TYPE_VOLTAGE_MONITOR |@ref bpmp_adc_ids | */ @@ -2826,16 +3481,16 @@ struct ec_err_vmon_desc { uint16_t desc_flags; /** @brief VMON rail adc id */ uint16_t vmon_adc_id; - /** @brief Bitmask of @ref bpmp_vmon_faults_flags */ + /** @brief Bitmask of bpmp_vmon_faults_flags */ uint32_t vmon_faults; /** @brief VMON faults access error */ int32_t vmon_access_error; } BPMP_ABI_PACKED; /** - * |error type | reg_id values | - * |---------------------------------|---------------------------| - * |@ref EC_ERR_TYPE_REGISTER_PARITY |@ref bpmp_ec_registers_ids | + * |error type | reg_id values | + * |---------------------------------|-----------------------| + * |@ref EC_ERR_TYPE_REGISTER_PARITY | bpmp_ec_registers_ids | */ struct ec_err_reg_parity_desc { /** @brief Bitmask of @ref bpmp_ec_desc_flags */ @@ -2847,10 +3502,10 @@ struct ec_err_reg_parity_desc { } BPMP_ABI_PACKED; /** - * |error type | err_source_id values | - * |--------------------------------- |--------------------------| - * |@ref EC_ERR_TYPE_SW_CORRECTABLE | @ref bpmp_ec_ce_swd_ids | - * |@ref EC_ERR_TYPE_SW_UNCORRECTABLE | @ref bpmp_ec_ue_swd_ids | + * |error type | err_source_id values | + * |--------------------------------- |----------------------| + * |@ref EC_ERR_TYPE_SW_CORRECTABLE | bpmp_ec_ce_swd_ids | + * |@ref EC_ERR_TYPE_SW_UNCORRECTABLE | bpmp_ec_ue_swd_ids | */ struct ec_err_sw_error_desc { /** @brief Bitmask of @ref bpmp_ec_desc_flags */ @@ -2862,15 +3517,15 @@ struct ec_err_sw_error_desc { } BPMP_ABI_PACKED; /** - * |error type | err_source_id values | - * |----------------------------------------|---------------------------| - * |@ref EC_ERR_TYPE_PARITY_INTERNAL |@ref bpmp_ec_ipath_ids | - * |@ref EC_ERR_TYPE_ECC_SEC_INTERNAL |@ref bpmp_ec_ipath_ids | - * |@ref EC_ERR_TYPE_ECC_DED_INTERNAL |@ref bpmp_ec_ipath_ids | - * |@ref EC_ERR_TYPE_COMPARATOR |@ref bpmp_ec_comparator_ids| - * |@ref EC_ERR_TYPE_PARITY_SRAM |@ref bpmp_clock_ids | - * |@ref EC_ERR_TYPE_OTHER_HW_CORRECTABLE |@ref bpmp_ec_misc_hwd_ids | - * |@ref EC_ERR_TYPE_OTHER_HW_UNCORRECTABLE |@ref bpmp_ec_misc_hwd_ids | + * |error type | err_source_id values | + * |----------------------------------------|------------------------| + * |@ref EC_ERR_TYPE_PARITY_INTERNAL | bpmp_ec_ipath_ids | + * |@ref EC_ERR_TYPE_ECC_SEC_INTERNAL | bpmp_ec_ipath_ids | + * |@ref EC_ERR_TYPE_ECC_DED_INTERNAL | bpmp_ec_ipath_ids | + * |@ref EC_ERR_TYPE_COMPARATOR | bpmp_ec_comparator_ids| + * |@ref EC_ERR_TYPE_OTHER_HW_CORRECTABLE | bpmp_ec_misc_hwd_ids | + * |@ref EC_ERR_TYPE_OTHER_HW_UNCORRECTABLE | bpmp_ec_misc_hwd_ids | + * |@ref EC_ERR_TYPE_PARITY_SRAM | bpmp_clock_ids | */ struct ec_err_simple_desc { /** @brief Bitmask of @ref bpmp_ec_desc_flags */ @@ -2917,7 +3572,7 @@ struct cmd_ec_status_get_response { /** @brief EC error descriptors */ union ec_err_desc error_descs[EC_ERR_STATUS_DESC_MAX_NUM]; } BPMP_ABI_PACKED; -/** @endcond */ +/** @endcond DEPRECATED */ struct cmd_ec_status_ex_get_response { /** @brief Target EC id (the same id received with request). */ @@ -2955,7 +3610,7 @@ struct cmd_ec_status_ex_get_response { * |sub-command |payload | * |----------------------------|-----------------------| * |@ref CMD_EC_STATUS_GET |ec_status_get | - * @endcond + * @endcond DEPRECATED * * |sub-command |payload | * |----------------------------|-----------------------| @@ -2983,7 +3638,7 @@ struct mrq_ec_request { * |sub-command |payload | * |----------------------------|------------------------| * |@ref CMD_EC_STATUS_GET |ec_status_get | - * @endcond + * @endcond DEPRECATED * * |sub-command |payload | * |----------------------------|------------------------| @@ -2997,13 +3652,264 @@ struct mrq_ec_response { * @cond DEPRECATED */ struct cmd_ec_status_get_response ec_status_get; - /** @endcond */ + /** @endcond DEPRECATED */ struct cmd_ec_status_ex_get_response ec_status_ex_get; } BPMP_UNION_ANON; } BPMP_ABI_PACKED; -/** @} */ -/** @endcond */ +/** @endcond bpmp_t194 */ +/** @} EC */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_TELEMETRY + * @brief Get address of memory buffer refreshed with recently sampled + * telemetry data + * + * * Platforms: TH500 onwards + * @cond bpmp_th500 + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: N/A + * * Response Payload: @ref mrq_telemetry_response + * @addtogroup Telemetry + * @{ + */ + +/** + * @brief Response to #MRQ_TELEMETRY + * + * mrq_response::err is + * * 0: Telemetry data is available at returned address + * * -#BPMP_EACCES: MRQ master is not allowed to request buffer refresh + * * -#BPMP_ENAVAIL: Telemetry buffer cannot be refreshed via this MRQ channel + * * -#BPMP_ENOTSUP: Telemetry buffer is not supported by BPMP-FW + * * -#BPMP_ENODEV: Telemetry mrq is not supported by BPMP-FW + */ +struct mrq_telemetry_response { + /** @brief Physical address of telemetry data buffer */ + uint64_t data_buf_addr; /**< see @ref bpmp_telemetry_layout */ +} BPMP_ABI_PACKED; + +/** @} Telemetry */ +/** @endcond bpmp_th500 */ + +/** + * @ingroup MRQ_Codes + * @def MRQ_PWR_LIMIT + * @brief Control power limits. + * + * * Platforms: TH500 onwards + * @cond bpmp_th500 + * * Initiators: Any + * * Targets: BPMP + * * Request Payload: @ref mrq_pwr_limit_request + * * Response Payload: @ref mrq_pwr_limit_response + * + * @addtogroup Pwrlimit + * @{ + */ +enum mrq_pwr_limit_cmd { + /** + * @brief Check whether the BPMP-FW supports the specified + * command + * + * mrq_response::err is 0 if the specified request is + * supported and -#BPMP_ENODEV otherwise. + */ + CMD_PWR_LIMIT_QUERY_ABI = 0, + + /** + * @brief Set power limit + * + * mrq_response:err is + * * 0: Success + * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW + * * -#BPMP_ENAVAIL: Invalid request parameters + * * -#BPMP_EACCES: Request is not accepted + */ + CMD_PWR_LIMIT_SET = 1, + + /** + * @brief Get power limit setting + * + * mrq_response:err is + * * 0: Success + * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW + * * -#BPMP_ENAVAIL: Invalid request parameters + */ + CMD_PWR_LIMIT_GET = 2, + + /** + * @brief Get current power cap + * + * mrq_response:err is + * * 0: Success + * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW + * * -#BPMP_ENAVAIL: Invalid request parameters + */ + CMD_PWR_LIMIT_CURR_CAP = 3, +}; + +/** + * @defgroup bpmp_pwr_limit_type PWR_LIMIT TYPEs + * @{ + */ +/** @brief Limit value specifies traget cap */ +#define PWR_LIMIT_TYPE_TARGET_CAP 0U +/** @brief Limit value specifies maximum possible target cap */ +#define PWR_LIMIT_TYPE_BOUND_MAX 1U +/** @brief Limit value specifies minimum possible target cap */ +#define PWR_LIMIT_TYPE_BOUND_MIN 2U +/** @brief Number of limit types supported by mrq interface */ +#define PWR_LIMIT_TYPE_NUM 3U + +/** @} bpmp_pwr_limit_type */ + +/** + * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_QUERY_ABI + */ +struct cmd_pwr_limit_query_abi_request { + uint32_t cmd_code; /**< @ref mrq_pwr_limit_cmd */ +} BPMP_ABI_PACKED; + +/** + * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_SET + * + * Set specified limit of specified type from specified source. The success of + * the request means that specified value is accepted as input to arbitration + * with other sources settings for the same limit of the same type. Zero limit + * is ignored by the arbitration (i.e., indicates "no limit set"). + */ +struct cmd_pwr_limit_set_request { + uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */ + uint32_t limit_src; /**< @ref bpmp_pwr_limit_src */ + uint32_t limit_type; /**< @ref bpmp_pwr_limit_type */ + uint32_t limit_setting; +} BPMP_ABI_PACKED; + +/** + * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_GET + * + * Get previously set from specified source specified limit value of specified + * type. + */ +struct cmd_pwr_limit_get_request { + uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */ + uint32_t limit_src; /**< @ref bpmp_pwr_limit_src */ + uint32_t limit_type; /**< @ref bpmp_pwr_limit_type */ +} BPMP_ABI_PACKED; + +/** + * @brief Response data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_GET + */ +struct cmd_pwr_limit_get_response { + uint32_t limit_setting; +} BPMP_ABI_PACKED; + +/** + * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_CURR_CAP + * + * For specified limit get current power cap aggregated from all sources. + */ +struct cmd_pwr_limit_curr_cap_request { + uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */ +} BPMP_ABI_PACKED; + +/** + * @brief Response data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_CURR_CAP + */ +struct cmd_pwr_limit_curr_cap_response { + uint32_t curr_cap; +} BPMP_ABI_PACKED; + +/** + * @brief Request with #MRQ_PWR_LIMIT + * + * |sub-command |payload | + * |----------------------------|---------------------------------| + * |CMD_PWR_LIMIT_QUERY_ABI | cmd_pwr_limit_query_abi_request | + * |CMD_PWR_LIMIT_SET | cmd_pwr_limit_set_request | + * |CMD_PWR_LIMIT_GET | cmd_pwr_limit_get_request | + * |CMD_PWR_LIMIT_CURR_CAP | cmd_pwr_limit_curr_cap_request | + */ +struct mrq_pwr_limit_request { + uint32_t cmd; + union { + struct cmd_pwr_limit_query_abi_request pwr_limit_query_abi_req; + struct cmd_pwr_limit_set_request pwr_limit_set_req; + struct cmd_pwr_limit_get_request pwr_limit_get_req; + struct cmd_pwr_limit_curr_cap_request pwr_limit_curr_cap_req; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** + * @brief Response to MRQ_PWR_LIMIT + * + * |sub-command |payload | + * |----------------------------|---------------------------------| + * |CMD_PWR_LIMIT_QUERY_ABI | - | + * |CMD_PWR_LIMIT_SET | - | + * |CMD_PWR_LIMIT_GET | cmd_pwr_limit_get_response | + * |CMD_PWR_LIMIT_CURR_CAP | cmd_pwr_limit_curr_cap_response | + */ +struct mrq_pwr_limit_response { + union { + struct cmd_pwr_limit_get_response pwr_limit_get_rsp; + struct cmd_pwr_limit_curr_cap_response pwr_limit_curr_cap_rsp; + } BPMP_UNION_ANON; +} BPMP_ABI_PACKED; + +/** @} PwrLimit */ +/** @endcond bpmp_th500 */ + + +/** + * @ingroup MRQ_Codes + * @def MRQ_GEARS + * @brief Get thresholds for NDIV offset switching + * + * * Platforms: TH500 onwards + * @cond bpmp_th500 + * * Initiators: CCPLEX + * * Targets: BPMP + * * Request Payload: N/A + * * Response Payload: @ref mrq_gears_response + * @addtogroup Gears + * @{ + */ + +/** + * @brief Response to #MRQ_GEARS + * + * Used by the sender of an #MRQ_GEARS message to request thresholds + * for NDIV offset switching. + * + * The mrq_gears_response::ncpu array defines four thresholds in units + * of number of online CPUS to be used for choosing between five different + * NDIV offset settings for CCPLEX cluster NAFLLs + * + * 1. If number of online CPUs < ncpu[0] use offset0 + * 2. If number of online CPUs < ncpu[1] use offset1 + * 3. If number of online CPUs < ncpu[2] use offset2 + * 4. If number of online CPUs < ncpu[3] use offset3 + * 5. If number of online CPUs >= ncpu[3] disable offsetting + * + * For TH500 mrq_gears_response::ncpu array has four valid entries. + * + * mrq_response::err is + * * 0: gears defined and response data valid + * * -#BPMP_ENODEV: MRQ is not supported by BPMP-FW + * * -#BPMP_EACCES: Operation not permitted for the MRQ master + * * -#BPMP_ENAVAIL: NDIV offsetting is disabled + */ +struct mrq_gears_response { + /** @brief number of online CPUs for each gear */ + uint32_t ncpu[16]; +} BPMP_ABI_PACKED; + +/** @} Gears */ +/** @endcond bpmp_th500 */ /** * @addtogroup Error_Codes @@ -3047,12 +3953,18 @@ struct mrq_ec_response { #define BPMP_ENOSYS 38 /** @brief Invalid slot */ #define BPMP_EBADSLT 57 +/** @brief Invalid message */ +#define BPMP_EBADMSG 77 +/** @brief Operation not supported */ +#define BPMP_EOPNOTSUPP 95 +/** @brief Targeted resource not available */ +#define BPMP_ENAVAIL 119 /** @brief Not supported */ #define BPMP_ENOTSUP 134 /** @brief No such device or address */ #define BPMP_ENXIO 140 -/** @} */ +/** @} Error_Codes */ #if defined(BPMP_ABI_CHECKS) #include "bpmp_abi_checks.h" diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h index f2604e99af09..f5e4ac5b8cce 100644 --- a/include/soc/tegra/bpmp.h +++ b/include/soc/tegra/bpmp.h @@ -6,6 +6,7 @@ #ifndef __SOC_TEGRA_BPMP_H #define __SOC_TEGRA_BPMP_H +#include <linux/iosys-map.h> #include <linux/mailbox_client.h> #include <linux/pm_domain.h> #include <linux/reset-controller.h> @@ -36,10 +37,22 @@ struct tegra_bpmp_mb_data { u8 data[MSG_DATA_MIN_SZ]; } __packed; +#define tegra_bpmp_mb_read(dst, mb, size) \ + iosys_map_memcpy_from(dst, mb, offsetof(struct tegra_bpmp_mb_data, data), size) + +#define tegra_bpmp_mb_write(mb, src, size) \ + iosys_map_memcpy_to(mb, offsetof(struct tegra_bpmp_mb_data, data), src, size) + +#define tegra_bpmp_mb_read_field(mb, field) \ + iosys_map_rd_field(mb, 0, struct tegra_bpmp_mb_data, field) + +#define tegra_bpmp_mb_write_field(mb, field, value) \ + iosys_map_wr_field(mb, 0, struct tegra_bpmp_mb_data, field, value) + struct tegra_bpmp_channel { struct tegra_bpmp *bpmp; - struct tegra_bpmp_mb_data *ib; - struct tegra_bpmp_mb_data *ob; + struct iosys_map ib; + struct iosys_map ob; struct completion completion; struct tegra_ivc *ivc; unsigned int index; @@ -89,8 +102,12 @@ struct tegra_bpmp { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_mirror; #endif + + bool suspended; }; +#define TEGRA_BPMP_MESSAGE_RESET BIT(0) + struct tegra_bpmp_message { unsigned int mrq; @@ -104,6 +121,8 @@ struct tegra_bpmp_message { size_t size; int ret; } rx; + + unsigned long flags; }; #if IS_ENABLED(CONFIG_TEGRA_BPMP) diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h index 98027a76ce3d..8ec1ac07fc85 100644 --- a/include/soc/tegra/common.h +++ b/include/soc/tegra/common.h @@ -6,6 +6,52 @@ #ifndef __SOC_TEGRA_COMMON_H__ #define __SOC_TEGRA_COMMON_H__ +#include <linux/errno.h> +#include <linux/types.h> + +struct device; + +/** + * Tegra SoC core device OPP table configuration + * + * @init_state: pre-initialize OPP state of a device + */ +struct tegra_core_opp_params { + bool init_state; +}; + +#ifdef CONFIG_ARCH_TEGRA bool soc_is_tegra(void); +int devm_tegra_core_dev_init_opp_table(struct device *dev, + struct tegra_core_opp_params *params); +#else +static inline bool soc_is_tegra(void) +{ + return false; +} + +static inline int +devm_tegra_core_dev_init_opp_table(struct device *dev, + struct tegra_core_opp_params *params) +{ + return -ENODEV; +} +#endif + +static inline int +devm_tegra_core_dev_init_opp_table_common(struct device *dev) +{ + struct tegra_core_opp_params opp_params = {}; + int err; + + opp_params.init_state = true; + + err = devm_tegra_core_dev_init_opp_table(dev, &opp_params); + if (err != -ENODEV) + return err; + + return 0; +} + #endif /* __SOC_TEGRA_COMMON_H__ */ diff --git a/include/soc/tegra/emc.h b/include/soc/tegra/emc.h deleted file mode 100644 index 05199a97ccf4..000000000000 --- a/include/soc/tegra/emc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2014 NVIDIA Corporation. All rights reserved. - */ - -#ifndef __SOC_TEGRA_EMC_H__ -#define __SOC_TEGRA_EMC_H__ - -struct tegra_emc; - -int tegra_emc_prepare_timing_change(struct tegra_emc *emc, - unsigned long rate); -void tegra_emc_complete_timing_change(struct tegra_emc *emc, - unsigned long rate); - -#endif /* __SOC_TEGRA_EMC_H__ */ diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index 1097feca41ed..8f421b9f7585 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -1,11 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2012-2023, NVIDIA CORPORATION. All rights reserved. */ #ifndef __SOC_TEGRA_FUSE_H__ #define __SOC_TEGRA_FUSE_H__ +#include <linux/types.h> + #define TEGRA20 0x20 #define TEGRA30 0x30 #define TEGRA114 0x35 @@ -14,6 +16,9 @@ #define TEGRA210 0x21 #define TEGRA186 0x18 #define TEGRA194 0x19 +#define TEGRA234 0x23 +#define TEGRA241 0x24 +#define TEGRA264 0x26 #define TEGRA_FUSE_SKU_CALIB_0 0xf0 #define TEGRA30_FUSE_SATA_CALIB 0x124 @@ -21,9 +26,6 @@ #ifndef __ASSEMBLY__ -u32 tegra_read_chipid(void); -u8 tegra_get_chip_id(void); - enum tegra_revision { TEGRA_REVISION_UNKNOWN = 0, TEGRA_REVISION_A01, @@ -34,6 +36,20 @@ enum tegra_revision { TEGRA_REVISION_MAX, }; +enum tegra_platform { + TEGRA_PLATFORM_SILICON = 0, + TEGRA_PLATFORM_QT, + TEGRA_PLATFORM_SYSTEM_FPGA, + TEGRA_PLATFORM_UNIT_FPGA, + TEGRA_PLATFORM_ASIM_QT, + TEGRA_PLATFORM_ASIM_LINSIM, + TEGRA_PLATFORM_DSIM_ASIM_LINSIM, + TEGRA_PLATFORM_VERIFICATION_SIMULATION, + TEGRA_PLATFORM_VDK, + TEGRA_PLATFORM_VSP, + TEGRA_PLATFORM_MAX, +}; + struct tegra_sku_info { int sku_id; int cpu_process_id; @@ -47,13 +63,62 @@ struct tegra_sku_info { int gpu_speedo_id; int gpu_speedo_value; enum tegra_revision revision; + enum tegra_platform platform; }; +#ifdef CONFIG_ARCH_TEGRA +extern struct tegra_sku_info tegra_sku_info; u32 tegra_read_straps(void); u32 tegra_read_ram_code(void); int tegra_fuse_readl(unsigned long offset, u32 *value); +u32 tegra_read_chipid(void); +u8 tegra_get_chip_id(void); +u8 tegra_get_platform(void); +bool tegra_is_silicon(void); +int tegra194_miscreg_mask_serror(void); +#else +static struct tegra_sku_info tegra_sku_info __maybe_unused; -extern struct tegra_sku_info tegra_sku_info; +static inline u32 tegra_read_straps(void) +{ + return 0; +} + +static inline u32 tegra_read_ram_code(void) +{ + return 0; +} + +static inline int tegra_fuse_readl(unsigned long offset, u32 *value) +{ + return -ENODEV; +} + +static inline u32 tegra_read_chipid(void) +{ + return 0; +} + +static inline u8 tegra_get_chip_id(void) +{ + return 0; +} + +static inline u8 tegra_get_platform(void) +{ + return 0; +} + +static inline bool tegra_is_silicon(void) +{ + return false; +} + +static inline int tegra194_miscreg_mask_serror(void) +{ + return false; +} +#endif struct device *tegra_soc_device_register(void); diff --git a/include/soc/tegra/irq.h b/include/soc/tegra/irq.h index 8eb11a7109e4..94539551c8c1 100644 --- a/include/soc/tegra/irq.h +++ b/include/soc/tegra/irq.h @@ -6,8 +6,15 @@ #ifndef __SOC_TEGRA_IRQ_H #define __SOC_TEGRA_IRQ_H -#if defined(CONFIG_ARM) +#include <linux/types.h> + +#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) bool tegra_pending_sgi(void); +#else +static inline bool tegra_pending_sgi(void) +{ + return false; +} #endif #endif /* __SOC_TEGRA_IRQ_H */ diff --git a/include/soc/tegra/ivc.h b/include/soc/tegra/ivc.h index 4aeb77cc22c5..be45d5f5adea 100644 --- a/include/soc/tegra/ivc.h +++ b/include/soc/tegra/ivc.h @@ -4,9 +4,11 @@ */ #ifndef __TEGRA_IVC_H +#define __TEGRA_IVC_H #include <linux/device.h> #include <linux/dma-mapping.h> +#include <linux/iosys-map.h> #include <linux/types.h> struct tegra_ivc_header; @@ -15,7 +17,7 @@ struct tegra_ivc { struct device *peer; struct { - struct tegra_ivc_header *channel; + struct iosys_map map; unsigned int position; dma_addr_t phys; } rx, tx; @@ -36,7 +38,7 @@ struct tegra_ivc { * * Returns a pointer to the frame, or an error encoded pointer. */ -void *tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc); +int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, struct iosys_map *map); /** * tegra_ivc_read_advance - Advance the read queue @@ -56,7 +58,7 @@ int tegra_ivc_read_advance(struct tegra_ivc *ivc); * * Returns a pointer to the frame, or an error encoded pointer. */ -void *tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc); +int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, struct iosys_map *map); /** * tegra_ivc_write_advance - Advance the write queue @@ -91,8 +93,8 @@ void tegra_ivc_reset(struct tegra_ivc *ivc); size_t tegra_ivc_align(size_t size); unsigned tegra_ivc_total_queue_size(unsigned queue_size); -int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, void *rx, - dma_addr_t rx_phys, void *tx, dma_addr_t tx_phys, +int tegra_ivc_init(struct tegra_ivc *ivc, struct device *peer, const struct iosys_map *rx, + dma_addr_t rx_phys, const struct iosys_map *tx, dma_addr_t tx_phys, unsigned int num_frames, size_t frame_size, void (*notify)(struct tegra_ivc *ivc, void *data), void *data); diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 1238e35653d1..6ee4c59db620 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -6,42 +6,63 @@ #ifndef __SOC_TEGRA_MC_H__ #define __SOC_TEGRA_MC_H__ +#include <linux/bits.h> +#include <linux/debugfs.h> #include <linux/err.h> +#include <linux/interconnect-provider.h> +#include <linux/irq.h> #include <linux/reset-controller.h> #include <linux/types.h> +#include <linux/tegra-icc.h> struct clk; struct device; struct page; -struct tegra_smmu_enable { - unsigned int reg; - unsigned int bit; -}; - struct tegra_mc_timing { unsigned long rate; u32 *emem_data; }; -/* latency allowance */ -struct tegra_mc_la { - unsigned int reg; - unsigned int shift; - unsigned int mask; - unsigned int def; -}; - struct tegra_mc_client { unsigned int id; + unsigned int bpmp_id; + enum tegra_icc_client_type type; const char *name; - unsigned int swgroup; + /* + * For Tegra210 and earlier, this is the SWGROUP ID used for IOVA translations in the + * Tegra SMMU, whereas on Tegra186 and later this is the ID used to override the ARM SMMU + * stream ID used for IOVA translations for the given memory client. + */ + union { + unsigned int swgroup; + unsigned int sid; + }; unsigned int fifo_size; - struct tegra_smmu_enable smmu; - struct tegra_mc_la la; + struct { + /* Tegra SMMU enable (Tegra210 and earlier) */ + struct { + unsigned int reg; + unsigned int bit; + } smmu; + + /* latency allowance */ + struct { + unsigned int reg; + unsigned int shift; + unsigned int mask; + unsigned int def; + } la; + + /* stream ID overrides (Tegra186 and later) */ + struct { + unsigned int override; + unsigned int security; + } sid; + } regs; }; struct tegra_smmu_swgroup { @@ -75,7 +96,6 @@ struct tegra_smmu_soc { struct tegra_mc; struct tegra_smmu; -struct gart_device; #ifdef CONFIG_TEGRA_IOMMU_SMMU struct tegra_smmu *tegra_smmu_probe(struct device *dev, @@ -95,28 +115,6 @@ static inline void tegra_smmu_remove(struct tegra_smmu *smmu) } #endif -#ifdef CONFIG_TEGRA_IOMMU_GART -struct gart_device *tegra_gart_probe(struct device *dev, struct tegra_mc *mc); -int tegra_gart_suspend(struct gart_device *gart); -int tegra_gart_resume(struct gart_device *gart); -#else -static inline struct gart_device * -tegra_gart_probe(struct device *dev, struct tegra_mc *mc) -{ - return ERR_PTR(-ENODEV); -} - -static inline int tegra_gart_suspend(struct gart_device *gart) -{ - return -ENODEV; -} - -static inline int tegra_gart_resume(struct gart_device *gart) -{ - return -ENODEV; -} -#endif - struct tegra_mc_reset { const char *name; unsigned long id; @@ -141,6 +139,35 @@ struct tegra_mc_reset_ops { const struct tegra_mc_reset *rst); }; +#define TEGRA_MC_ICC_TAG_DEFAULT 0 +#define TEGRA_MC_ICC_TAG_ISO BIT(0) + +struct tegra_mc_icc_ops { + int (*set)(struct icc_node *src, struct icc_node *dst); + int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw, + u32 peak_bw, u32 *agg_avg, u32 *agg_peak); + struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data); + struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec, + void *data); + int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak); +}; + +struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec, + void *data); +extern const struct tegra_mc_icc_ops tegra_mc_icc_ops; + +struct tegra_mc_ops { + /* + * @probe: Callback to set up SoC-specific bits of the memory controller. This is called + * after basic, common set up that is done by the SoC-agnostic bits. + */ + int (*probe)(struct tegra_mc *mc); + void (*remove)(struct tegra_mc *mc); + int (*resume)(struct tegra_mc *mc); + irqreturn_t (*handle_irq)(int irq, void *data); + int (*probe_device)(struct tegra_mc *mc, struct device *dev); +}; + struct tegra_mc_soc { const struct tegra_mc_client *clients; unsigned int num_clients; @@ -151,22 +178,33 @@ struct tegra_mc_soc { unsigned int num_address_bits; unsigned int atom_size; - u8 client_id_mask; + unsigned int num_carveouts; + + u16 client_id_mask; + u8 num_channels; const struct tegra_smmu_soc *smmu; u32 intmask; + u32 ch_intmask; + u32 global_intstatus_channel_shift; + bool has_addr_hi_reg; const struct tegra_mc_reset_ops *reset_ops; const struct tegra_mc_reset *resets; unsigned int num_resets; + + const struct tegra_mc_icc_ops *icc_ops; + const struct tegra_mc_ops *ops; }; struct tegra_mc { + struct tegra_bpmp *bpmp; struct device *dev; struct tegra_smmu *smmu; - struct gart_device *gart; void __iomem *regs; + void __iomem *bcast_ch_regs; + void __iomem **ch_regs; struct clk *clk; int irq; @@ -175,13 +213,47 @@ struct tegra_mc { struct tegra_mc_timing *timings; unsigned int num_timings; + unsigned int num_channels; + bool bwmgr_mrq_supported; struct reset_controller_dev reset; + struct icc_provider provider; + spinlock_t lock; + + struct { + struct dentry *root; + } debugfs; }; int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate); unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc); +#ifdef CONFIG_TEGRA_MC +struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev); +int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev); +int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size); +#else +static inline struct tegra_mc * +devm_tegra_memory_controller_get(struct device *dev) +{ + return ERR_PTR(-ENODEV); +} + +static inline int +tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev) +{ + return -ENODEV; +} + +static inline int +tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size) +{ + return -ENODEV; +} +#endif + #endif /* __SOC_TEGRA_MC_H__ */ diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h index 08477d7bfab9..ce4d0b1bd0d6 100644 --- a/include/soc/tegra/pm.h +++ b/include/soc/tegra/pm.h @@ -14,9 +14,10 @@ enum tegra_suspend_mode { TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ TEGRA_MAX_SUSPEND_MODE, + TEGRA_SUSPEND_NOT_READY, }; -#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) enum tegra_suspend_mode tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode); @@ -28,6 +29,7 @@ void tegra_pm_clear_cpu_in_lp2(void); void tegra_pm_set_cpu_in_lp2(void); int tegra_pm_enter_lp2(void); int tegra_pm_park_secondary_cpu(unsigned long cpu); +void tegra_pm_init_suspend(void); #else static inline enum tegra_suspend_mode tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode) @@ -61,6 +63,10 @@ static inline int tegra_pm_park_secondary_cpu(unsigned long cpu) { return -ENOTSUPP; } + +static inline void tegra_pm_init_suspend(void) +{ +} #endif /* CONFIG_PM_SLEEP */ #endif /* __SOC_TEGRA_PM_H__ */ diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h index 361cb64246f7..c545875d0ff1 100644 --- a/include/soc/tegra/pmc.h +++ b/include/soc/tegra/pmc.h @@ -118,9 +118,9 @@ enum tegra_io_pad { TEGRA_IO_PAD_PEX_CLK_2, TEGRA_IO_PAD_PEX_CNTRL, TEGRA_IO_PAD_PEX_CTL2, - TEGRA_IO_PAD_PEX_L0_RST_N, - TEGRA_IO_PAD_PEX_L1_RST_N, - TEGRA_IO_PAD_PEX_L5_RST_N, + TEGRA_IO_PAD_PEX_L0_RST, + TEGRA_IO_PAD_PEX_L1_RST, + TEGRA_IO_PAD_PEX_L5_RST, TEGRA_IO_PAD_PWR_CTL, TEGRA_IO_PAD_SDMMC1, TEGRA_IO_PAD_SDMMC1_HV, @@ -148,10 +148,6 @@ enum tegra_io_pad { TEGRA_IO_PAD_AO_HV, }; -/* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */ -#define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI -#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS - #ifdef CONFIG_SOC_TEGRA_PMC int tegra_powergate_power_on(unsigned int id); int tegra_powergate_power_off(unsigned int id); @@ -164,13 +160,11 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, int tegra_io_pad_power_enable(enum tegra_io_pad id); int tegra_io_pad_power_disable(enum tegra_io_pad id); -/* deprecated, use tegra_io_pad_power_{enable,disable}() instead */ -int tegra_io_rail_power_on(unsigned int id); -int tegra_io_rail_power_off(unsigned int id); - void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); +bool tegra_pmc_core_domain_state_synced(void); + #else static inline int tegra_powergate_power_on(unsigned int id) { @@ -209,22 +203,17 @@ static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id) return -ENOSYS; } -static inline int tegra_io_rail_power_on(unsigned int id) -{ - return -ENOSYS; -} - -static inline int tegra_io_rail_power_off(unsigned int id) +static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode) { - return -ENOSYS; } -static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode) +static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode) { } -static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode) +static inline bool tegra_pmc_core_domain_state_synced(void) { + return false; } #endif /* CONFIG_SOC_TEGRA_PMC */ diff --git a/include/soc/tegra/tegra-cbb.h b/include/soc/tegra/tegra-cbb.h new file mode 100644 index 000000000000..e864c2ebe794 --- /dev/null +++ b/include/soc/tegra/tegra-cbb.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved + */ + +#ifndef TEGRA_CBB_H +#define TEGRA_CBB_H + +#include <linux/list.h> + +struct tegra_cbb_error { + const char *code; + const char *source; + const char *desc; +}; + +struct tegra_cbb { + struct device *dev; + const struct tegra_cbb_ops *ops; + struct list_head node; +}; + +struct tegra_cbb_ops { + int (*debugfs_show)(struct tegra_cbb *cbb, struct seq_file *s, void *v); + int (*interrupt_enable)(struct tegra_cbb *cbb); + void (*error_enable)(struct tegra_cbb *cbb); + void (*fault_enable)(struct tegra_cbb *cbb); + void (*stall_enable)(struct tegra_cbb *cbb); + void (*error_clear)(struct tegra_cbb *cbb); + u32 (*get_status)(struct tegra_cbb *cbb); +}; + +int tegra_cbb_get_irq(struct platform_device *pdev, unsigned int *nonsec_irq, + unsigned int *sec_irq); +__printf(2, 3) +void tegra_cbb_print_err(struct seq_file *file, const char *fmt, ...); + +void tegra_cbb_print_cache(struct seq_file *file, u32 cache); +void tegra_cbb_print_prot(struct seq_file *file, u32 prot); +int tegra_cbb_register(struct tegra_cbb *cbb); + +void tegra_cbb_fault_enable(struct tegra_cbb *cbb); +void tegra_cbb_stall_enable(struct tegra_cbb *cbb); +void tegra_cbb_error_clear(struct tegra_cbb *cbb); +u32 tegra_cbb_get_status(struct tegra_cbb *cbb); + +#endif /* TEGRA_CBB_H */ |