summaryrefslogtreecommitdiff
path: root/include/linux/soc/qcom/ubwc.h
blob: f3a70360b177bbf5a9ff71b8730368cd3342e4e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* 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 <linux/bits.h>
#include <linux/err.h>
#include <linux/printk.h>
#include <linux/types.h>

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__ */