/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef __QCOM_UBWC_H__ #define __QCOM_UBWC_H__ #include #include #include #include struct qcom_ubwc_cfg_data { u32 ubwc_enc_version; /** * @highest_bank_bit: Highest Bank Bit * * The Highest Bank Bit value represents the bit of the highest * DDR bank. This should ideally use DRAM type detection. */ int highest_bank_bit; unsigned int flags; #define UBWC_FLAG_DISABLE_SWIZZLE_LVL2 BIT(0) #define UBWC_FLAG_DISABLE_SWIZZLE_LVL3 BIT(1) }; #define UBWC_1_0 0x10000000 #define UBWC_2_0 0x20000000 #define UBWC_3_0 0x30000000 #define UBWC_3_1 0x30010000 /* UBWC 3.0 + Macrotile mode */ #define UBWC_4_0 0x40000000 #define UBWC_4_3 0x40030000 #define UBWC_5_0 0x50000000 #define UBWC_6_0 0x60000000 #if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG) const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void); #else static inline const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void) { return ERR_PTR(-EOPNOTSUPP); } #endif static inline bool qcom_ubwc_get_ubwc_mode(const struct qcom_ubwc_cfg_data *cfg) { return cfg->ubwc_enc_version == UBWC_1_0; } static inline bool qcom_ubwc_min_acc_length_64b(const struct qcom_ubwc_cfg_data *cfg) { return cfg->ubwc_enc_version == UBWC_1_0; } /* * @qcom_ubwc_macrotile_mode: whether to use 4-channel or 8-channel macrotiling * * The 8-channel macrotiling mode was introduced in UBWC 3.1. * * Returns: false for the 4-channel and true for 8-channel. */ static inline bool qcom_ubwc_macrotile_mode(const struct qcom_ubwc_cfg_data *cfg) { return cfg->ubwc_enc_version >= UBWC_3_1; } static inline bool qcom_ubwc_bank_spread(const struct qcom_ubwc_cfg_data *cfg) { return true; } #define UBWC_SWIZZLE_ENABLE_LVL1 BIT(0) #define UBWC_SWIZZLE_ENABLE_LVL2 BIT(1) #define UBWC_SWIZZLE_ENABLE_LVL3 BIT(2) /** * @qcom_ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling. * * UBWC 1.0 always enables all three levels. * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3. * UBWC 4.0 adds the optional ability to disable levels 2 & 3. */ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) { if (cfg->ubwc_enc_version == 0) return 0; if (cfg->ubwc_enc_version == UBWC_1_0) return UBWC_SWIZZLE_ENABLE_LVL1 | UBWC_SWIZZLE_ENABLE_LVL2 | UBWC_SWIZZLE_ENABLE_LVL3; u32 ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | UBWC_SWIZZLE_ENABLE_LVL3; if (cfg->flags & UBWC_FLAG_DISABLE_SWIZZLE_LVL2) ubwc_swizzle &= ~UBWC_SWIZZLE_ENABLE_LVL2; if (cfg->flags & UBWC_FLAG_DISABLE_SWIZZLE_LVL3) ubwc_swizzle &= ~UBWC_SWIZZLE_ENABLE_LVL3; return ubwc_swizzle; } static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg) { if (cfg->ubwc_enc_version >= UBWC_6_0) return 5; if (cfg->ubwc_enc_version >= UBWC_5_0) return 4; if (cfg->ubwc_enc_version >= UBWC_4_3) return 3; if (cfg->ubwc_enc_version >= UBWC_4_0) return 2; if (cfg->ubwc_enc_version >= UBWC_3_0) return 1; return 0; } static inline bool qcom_ubwc_enable_amsbc(const struct qcom_ubwc_cfg_data *cfg) { return cfg->ubwc_enc_version >= UBWC_3_0; } #endif /* __QCOM_UBWC_H__ */