xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_l2_mmu_config.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3  *
4  * (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
5  *
6  * This program is free software and is provided to you under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation, and any use by you of this program is subject to the terms
9  * of such GNU license.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you can access it online at
18  * http://www.gnu.org/licenses/gpl-2.0.html.
19  *
20  */
21 
22 #include <mali_kbase.h>
23 #include <mali_kbase_bits.h>
24 #include <mali_kbase_config_defaults.h>
25 #include <device/mali_kbase_device.h>
26 #include "mali_kbase_l2_mmu_config.h"
27 
28 /**
29  * struct l2_mmu_config_limit_region - L2 MMU limit field
30  *
31  * @value:    The default value to load into the L2_MMU_CONFIG register
32  * @mask:     The shifted mask of the field in the L2_MMU_CONFIG register
33  * @shift:    The shift of where the field starts in the L2_MMU_CONFIG register
34  *            This should be the same value as the smaller of the two mask
35  *            values
36  */
37 struct l2_mmu_config_limit_region {
38 	u32 value, mask, shift;
39 };
40 
41 /**
42  * struct l2_mmu_config_limit - L2 MMU read and write limit
43  *
44  * @product_model:    The GPU for which this entry applies
45  * @read:             Values for the read limit field
46  * @write:            Values for the write limit field
47  */
48 struct l2_mmu_config_limit {
49 	u32 product_model;
50 	struct l2_mmu_config_limit_region read;
51 	struct l2_mmu_config_limit_region write;
52 };
53 
54 /*
55  * Zero represents no limit
56  *
57  * For LBEX TBEX TBAX TTRX and TNAX:
58  *   The value represents the number of outstanding reads (6 bits) or writes (5 bits)
59  *
60  * For all other GPUS it is a fraction see: mali_kbase_config_defaults.h
61  */
62 static const struct l2_mmu_config_limit limits[] = {
63 	/* GPU, read, write */
64 	{GPU_ID2_PRODUCT_LBEX,
65 		{0, GENMASK(10, 5), 5},
66 		{0, GENMASK(16, 12), 12} },
67 	{GPU_ID2_PRODUCT_TBEX,
68 		{0, GENMASK(10, 5), 5},
69 		{0, GENMASK(16, 12), 12} },
70 	{GPU_ID2_PRODUCT_TBAX,
71 		{0, GENMASK(10, 5), 5},
72 		{0, GENMASK(16, 12), 12} },
73 	{GPU_ID2_PRODUCT_TTRX,
74 		{0, GENMASK(12, 7), 7},
75 		{0, GENMASK(17, 13), 13} },
76 	{GPU_ID2_PRODUCT_TNAX,
77 		{0, GENMASK(12, 7), 7},
78 		{0, GENMASK(17, 13), 13} },
79 	{GPU_ID2_PRODUCT_TGOX,
80 		{KBASE_3BIT_AID_32, GENMASK(14, 12), 12},
81 		{KBASE_3BIT_AID_32, GENMASK(17, 15), 15} },
82 	{GPU_ID2_PRODUCT_TNOX,
83 		{KBASE_3BIT_AID_32, GENMASK(14, 12), 12},
84 		{KBASE_3BIT_AID_32, GENMASK(17, 15), 15} },
85 };
86 
kbase_set_mmu_quirks(struct kbase_device * kbdev)87 int kbase_set_mmu_quirks(struct kbase_device *kbdev)
88 {
89 	/* All older GPUs had 2 bits for both fields, this is a default */
90 	struct l2_mmu_config_limit limit = {
91 		  0, /* Any GPU not in the limits array defined above */
92 		 {KBASE_AID_32, GENMASK(25, 24), 24},
93 		 {KBASE_AID_32, GENMASK(27, 26), 26}
94 		};
95 	u32 product_model, gpu_id;
96 	u32 mmu_config;
97 	int i;
98 
99 	gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
100 	product_model = gpu_id & GPU_ID2_PRODUCT_MODEL;
101 
102 	/* Limit the GPU bus bandwidth if the platform needs this. */
103 	for (i = 0; i < ARRAY_SIZE(limits); i++) {
104 		if (product_model == limits[i].product_model) {
105 			limit = limits[i];
106 			break;
107 		}
108 	}
109 
110 	mmu_config = kbase_reg_read(kbdev, GPU_CONTROL_REG(L2_MMU_CONFIG));
111 
112 	if (kbase_is_gpu_removed(kbdev))
113 		return -EIO;
114 
115 	mmu_config &= ~(limit.read.mask | limit.write.mask);
116 	/* Can't use FIELD_PREP() macro here as the mask isn't constant */
117 	mmu_config |= (limit.read.value << limit.read.shift) |
118 			(limit.write.value << limit.write.shift);
119 
120 	kbdev->hw_quirks_mmu = mmu_config;
121 
122 	if (kbdev->system_coherency == COHERENCY_ACE) {
123 		/* Allow memory configuration disparity to be ignored,
124 		 * we optimize the use of shared memory and thus we
125 		 * expect some disparity in the memory configuration.
126 		 */
127 		kbdev->hw_quirks_mmu |= L2_MMU_CONFIG_ALLOW_SNOOP_DISPARITY;
128 	}
129 
130 	return 0;
131 }
132