1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2015 MediaTek Inc. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/iopoll.h> 8 #include <linux/module.h> 9 #include <linux/of_device.h> 10 #include <linux/platform_device.h> 11 #include <linux/regmap.h> 12 #include <linux/soc/mediatek/mtk-mmsys.h> 13 #include <linux/soc/mediatek/mtk-mutex.h> 14 15 #define MT2701_MUTEX0_MOD0 0x2c 16 #define MT2701_MUTEX0_SOF0 0x30 17 #define MT8183_MUTEX0_MOD0 0x30 18 #define MT8183_MUTEX0_SOF0 0x2c 19 20 #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 21 #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 22 #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 23 #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 24 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 25 #define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 26 27 #define INT_MUTEX BIT(1) 28 29 #define MT8186_MUTEX_MOD_DISP_OVL0 0 30 #define MT8186_MUTEX_MOD_DISP_OVL0_2L 1 31 #define MT8186_MUTEX_MOD_DISP_RDMA0 2 32 #define MT8186_MUTEX_MOD_DISP_COLOR0 4 33 #define MT8186_MUTEX_MOD_DISP_CCORR0 5 34 #define MT8186_MUTEX_MOD_DISP_AAL0 7 35 #define MT8186_MUTEX_MOD_DISP_GAMMA0 8 36 #define MT8186_MUTEX_MOD_DISP_POSTMASK0 9 37 #define MT8186_MUTEX_MOD_DISP_DITHER0 10 38 #define MT8186_MUTEX_MOD_DISP_RDMA1 17 39 40 #define MT8186_MUTEX_SOF_SINGLE_MODE 0 41 #define MT8186_MUTEX_SOF_DSI0 1 42 #define MT8186_MUTEX_SOF_DPI0 2 43 #define MT8186_MUTEX_EOF_DSI0 (MT8186_MUTEX_SOF_DSI0 << 6) 44 #define MT8186_MUTEX_EOF_DPI0 (MT8186_MUTEX_SOF_DPI0 << 6) 45 46 #define MT8167_MUTEX_MOD_DISP_PWM 1 47 #define MT8167_MUTEX_MOD_DISP_OVL0 6 48 #define MT8167_MUTEX_MOD_DISP_OVL1 7 49 #define MT8167_MUTEX_MOD_DISP_RDMA0 8 50 #define MT8167_MUTEX_MOD_DISP_RDMA1 9 51 #define MT8167_MUTEX_MOD_DISP_WDMA0 10 52 #define MT8167_MUTEX_MOD_DISP_CCORR 11 53 #define MT8167_MUTEX_MOD_DISP_COLOR 12 54 #define MT8167_MUTEX_MOD_DISP_AAL 13 55 #define MT8167_MUTEX_MOD_DISP_GAMMA 14 56 #define MT8167_MUTEX_MOD_DISP_DITHER 15 57 #define MT8167_MUTEX_MOD_DISP_UFOE 16 58 59 #define MT8192_MUTEX_MOD_DISP_OVL0 0 60 #define MT8192_MUTEX_MOD_DISP_OVL0_2L 1 61 #define MT8192_MUTEX_MOD_DISP_RDMA0 2 62 #define MT8192_MUTEX_MOD_DISP_COLOR0 4 63 #define MT8192_MUTEX_MOD_DISP_CCORR0 5 64 #define MT8192_MUTEX_MOD_DISP_AAL0 6 65 #define MT8192_MUTEX_MOD_DISP_GAMMA0 7 66 #define MT8192_MUTEX_MOD_DISP_POSTMASK0 8 67 #define MT8192_MUTEX_MOD_DISP_DITHER0 9 68 #define MT8192_MUTEX_MOD_DISP_OVL2_2L 16 69 #define MT8192_MUTEX_MOD_DISP_RDMA4 17 70 71 #define MT8183_MUTEX_MOD_DISP_RDMA0 0 72 #define MT8183_MUTEX_MOD_DISP_RDMA1 1 73 #define MT8183_MUTEX_MOD_DISP_OVL0 9 74 #define MT8183_MUTEX_MOD_DISP_OVL0_2L 10 75 #define MT8183_MUTEX_MOD_DISP_OVL1_2L 11 76 #define MT8183_MUTEX_MOD_DISP_WDMA0 12 77 #define MT8183_MUTEX_MOD_DISP_COLOR0 13 78 #define MT8183_MUTEX_MOD_DISP_CCORR0 14 79 #define MT8183_MUTEX_MOD_DISP_AAL0 15 80 #define MT8183_MUTEX_MOD_DISP_GAMMA0 16 81 #define MT8183_MUTEX_MOD_DISP_DITHER0 17 82 83 #define MT8173_MUTEX_MOD_DISP_OVL0 11 84 #define MT8173_MUTEX_MOD_DISP_OVL1 12 85 #define MT8173_MUTEX_MOD_DISP_RDMA0 13 86 #define MT8173_MUTEX_MOD_DISP_RDMA1 14 87 #define MT8173_MUTEX_MOD_DISP_RDMA2 15 88 #define MT8173_MUTEX_MOD_DISP_WDMA0 16 89 #define MT8173_MUTEX_MOD_DISP_WDMA1 17 90 #define MT8173_MUTEX_MOD_DISP_COLOR0 18 91 #define MT8173_MUTEX_MOD_DISP_COLOR1 19 92 #define MT8173_MUTEX_MOD_DISP_AAL 20 93 #define MT8173_MUTEX_MOD_DISP_GAMMA 21 94 #define MT8173_MUTEX_MOD_DISP_UFOE 22 95 #define MT8173_MUTEX_MOD_DISP_PWM0 23 96 #define MT8173_MUTEX_MOD_DISP_PWM1 24 97 #define MT8173_MUTEX_MOD_DISP_OD 25 98 99 #define MT8195_MUTEX_MOD_DISP_OVL0 0 100 #define MT8195_MUTEX_MOD_DISP_WDMA0 1 101 #define MT8195_MUTEX_MOD_DISP_RDMA0 2 102 #define MT8195_MUTEX_MOD_DISP_COLOR0 3 103 #define MT8195_MUTEX_MOD_DISP_CCORR0 4 104 #define MT8195_MUTEX_MOD_DISP_AAL0 5 105 #define MT8195_MUTEX_MOD_DISP_GAMMA0 6 106 #define MT8195_MUTEX_MOD_DISP_DITHER0 7 107 #define MT8195_MUTEX_MOD_DISP_DSI0 8 108 #define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0 9 109 #define MT8195_MUTEX_MOD_DISP_VPP_MERGE 20 110 #define MT8195_MUTEX_MOD_DISP_DP_INTF0 21 111 #define MT8195_MUTEX_MOD_DISP_PWM0 27 112 113 #define MT2712_MUTEX_MOD_DISP_PWM2 10 114 #define MT2712_MUTEX_MOD_DISP_OVL0 11 115 #define MT2712_MUTEX_MOD_DISP_OVL1 12 116 #define MT2712_MUTEX_MOD_DISP_RDMA0 13 117 #define MT2712_MUTEX_MOD_DISP_RDMA1 14 118 #define MT2712_MUTEX_MOD_DISP_RDMA2 15 119 #define MT2712_MUTEX_MOD_DISP_WDMA0 16 120 #define MT2712_MUTEX_MOD_DISP_WDMA1 17 121 #define MT2712_MUTEX_MOD_DISP_COLOR0 18 122 #define MT2712_MUTEX_MOD_DISP_COLOR1 19 123 #define MT2712_MUTEX_MOD_DISP_AAL0 20 124 #define MT2712_MUTEX_MOD_DISP_UFOE 22 125 #define MT2712_MUTEX_MOD_DISP_PWM0 23 126 #define MT2712_MUTEX_MOD_DISP_PWM1 24 127 #define MT2712_MUTEX_MOD_DISP_OD0 25 128 #define MT2712_MUTEX_MOD2_DISP_AAL1 33 129 #define MT2712_MUTEX_MOD2_DISP_OD1 34 130 131 #define MT2701_MUTEX_MOD_DISP_OVL 3 132 #define MT2701_MUTEX_MOD_DISP_WDMA 6 133 #define MT2701_MUTEX_MOD_DISP_COLOR 7 134 #define MT2701_MUTEX_MOD_DISP_BLS 9 135 #define MT2701_MUTEX_MOD_DISP_RDMA0 10 136 #define MT2701_MUTEX_MOD_DISP_RDMA1 12 137 138 #define MT2712_MUTEX_SOF_SINGLE_MODE 0 139 #define MT2712_MUTEX_SOF_DSI0 1 140 #define MT2712_MUTEX_SOF_DSI1 2 141 #define MT2712_MUTEX_SOF_DPI0 3 142 #define MT2712_MUTEX_SOF_DPI1 4 143 #define MT2712_MUTEX_SOF_DSI2 5 144 #define MT2712_MUTEX_SOF_DSI3 6 145 #define MT8167_MUTEX_SOF_DPI0 2 146 #define MT8167_MUTEX_SOF_DPI1 3 147 #define MT8183_MUTEX_SOF_DSI0 1 148 #define MT8183_MUTEX_SOF_DPI0 2 149 #define MT8195_MUTEX_SOF_DSI0 1 150 #define MT8195_MUTEX_SOF_DSI1 2 151 #define MT8195_MUTEX_SOF_DP_INTF0 3 152 #define MT8195_MUTEX_SOF_DP_INTF1 4 153 #define MT8195_MUTEX_SOF_DPI0 6 /* for HDMI_TX */ 154 #define MT8195_MUTEX_SOF_DPI1 5 /* for digital video out */ 155 156 #define MT8183_MUTEX_EOF_DSI0 (MT8183_MUTEX_SOF_DSI0 << 6) 157 #define MT8183_MUTEX_EOF_DPI0 (MT8183_MUTEX_SOF_DPI0 << 6) 158 #define MT8195_MUTEX_EOF_DSI0 (MT8195_MUTEX_SOF_DSI0 << 7) 159 #define MT8195_MUTEX_EOF_DSI1 (MT8195_MUTEX_SOF_DSI1 << 7) 160 #define MT8195_MUTEX_EOF_DP_INTF0 (MT8195_MUTEX_SOF_DP_INTF0 << 7) 161 #define MT8195_MUTEX_EOF_DP_INTF1 (MT8195_MUTEX_SOF_DP_INTF1 << 7) 162 #define MT8195_MUTEX_EOF_DPI0 (MT8195_MUTEX_SOF_DPI0 << 7) 163 #define MT8195_MUTEX_EOF_DPI1 (MT8195_MUTEX_SOF_DPI1 << 7) 164 165 struct mtk_mutex { 166 int id; 167 bool claimed; 168 }; 169 170 enum mtk_mutex_sof_id { 171 MUTEX_SOF_SINGLE_MODE, 172 MUTEX_SOF_DSI0, 173 MUTEX_SOF_DSI1, 174 MUTEX_SOF_DPI0, 175 MUTEX_SOF_DPI1, 176 MUTEX_SOF_DSI2, 177 MUTEX_SOF_DSI3, 178 MUTEX_SOF_DP_INTF0, 179 MUTEX_SOF_DP_INTF1, 180 DDP_MUTEX_SOF_MAX, 181 }; 182 183 struct mtk_mutex_data { 184 const unsigned int *mutex_mod; 185 const unsigned int *mutex_sof; 186 const unsigned int mutex_mod_reg; 187 const unsigned int mutex_sof_reg; 188 const bool no_clk; 189 }; 190 191 struct mtk_mutex_ctx { 192 struct device *dev; 193 struct clk *clk; 194 void __iomem *regs; 195 struct mtk_mutex mutex[10]; 196 const struct mtk_mutex_data *data; 197 }; 198 199 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { 200 [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS, 201 [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR, 202 [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL, 203 [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0, 204 [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1, 205 [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA, 206 }; 207 208 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { 209 [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0, 210 [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1, 211 [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0, 212 [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1, 213 [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0, 214 [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1, 215 [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0, 216 [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1, 217 [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0, 218 [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1, 219 [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2, 220 [DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0, 221 [DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1, 222 [DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2, 223 [DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE, 224 [DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0, 225 [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1, 226 }; 227 228 static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = { 229 [DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL, 230 [DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR, 231 [DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR, 232 [DDP_COMPONENT_DITHER0] = MT8167_MUTEX_MOD_DISP_DITHER, 233 [DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA, 234 [DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0, 235 [DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1, 236 [DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM, 237 [DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0, 238 [DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1, 239 [DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE, 240 [DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0, 241 }; 242 243 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = { 244 [DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL, 245 [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0, 246 [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1, 247 [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA, 248 [DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD, 249 [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0, 250 [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1, 251 [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0, 252 [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1, 253 [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0, 254 [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1, 255 [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2, 256 [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE, 257 [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0, 258 [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1, 259 }; 260 261 static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = { 262 [DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0, 263 [DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0, 264 [DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0, 265 [DDP_COMPONENT_DITHER0] = MT8183_MUTEX_MOD_DISP_DITHER0, 266 [DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0, 267 [DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0, 268 [DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L, 269 [DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L, 270 [DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0, 271 [DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1, 272 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0, 273 }; 274 275 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { 276 [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0, 277 [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0, 278 [DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0, 279 [DDP_COMPONENT_DITHER0] = MT8186_MUTEX_MOD_DISP_DITHER0, 280 [DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0, 281 [DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0, 282 [DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L, 283 [DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0, 284 [DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0, 285 [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, 286 }; 287 288 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { 289 [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0, 290 [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0, 291 [DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0, 292 [DDP_COMPONENT_DITHER0] = MT8192_MUTEX_MOD_DISP_DITHER0, 293 [DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0, 294 [DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0, 295 [DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0, 296 [DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L, 297 [DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L, 298 [DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0, 299 [DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4, 300 }; 301 302 static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = { 303 [DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0, 304 [DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0, 305 [DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0, 306 [DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0, 307 [DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0, 308 [DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0, 309 [DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0, 310 [DDP_COMPONENT_DITHER0] = MT8195_MUTEX_MOD_DISP_DITHER0, 311 [DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE, 312 [DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0, 313 [DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0, 314 [DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0, 315 [DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0, 316 }; 317 318 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = { 319 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 320 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 321 [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, 322 [MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, 323 [MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1, 324 [MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2, 325 [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, 326 }; 327 328 static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = { 329 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 330 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 331 [MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0, 332 [MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1, 333 }; 334 335 /* Add EOF setting so overlay hardware can receive frame done irq */ 336 static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = { 337 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 338 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0, 339 [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0, 340 }; 341 342 static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = { 343 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 344 [MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0, 345 [MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0, 346 }; 347 348 /* 349 * To support refresh mode(video mode), DISP_REG_MUTEX_SOF should 350 * select the EOF source and configure the EOF plus timing from the 351 * module that provides the timing signal. 352 * So that MUTEX can not only send a STREAM_DONE event to GCE 353 * but also detect the error at end of frame(EAEOF) when EOF signal 354 * arrives. 355 */ 356 static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = { 357 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 358 [MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0, 359 [MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1, 360 [MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0, 361 [MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1, 362 [MUTEX_SOF_DP_INTF0] = 363 MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0, 364 [MUTEX_SOF_DP_INTF1] = 365 MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1, 366 }; 367 368 static const struct mtk_mutex_data mt2701_mutex_driver_data = { 369 .mutex_mod = mt2701_mutex_mod, 370 .mutex_sof = mt2712_mutex_sof, 371 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 372 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 373 }; 374 375 static const struct mtk_mutex_data mt2712_mutex_driver_data = { 376 .mutex_mod = mt2712_mutex_mod, 377 .mutex_sof = mt2712_mutex_sof, 378 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 379 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 380 }; 381 382 static const struct mtk_mutex_data mt8167_mutex_driver_data = { 383 .mutex_mod = mt8167_mutex_mod, 384 .mutex_sof = mt8167_mutex_sof, 385 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 386 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 387 .no_clk = true, 388 }; 389 390 static const struct mtk_mutex_data mt8173_mutex_driver_data = { 391 .mutex_mod = mt8173_mutex_mod, 392 .mutex_sof = mt2712_mutex_sof, 393 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 394 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 395 }; 396 397 static const struct mtk_mutex_data mt8183_mutex_driver_data = { 398 .mutex_mod = mt8183_mutex_mod, 399 .mutex_sof = mt8183_mutex_sof, 400 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 401 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 402 .no_clk = true, 403 }; 404 405 static const struct mtk_mutex_data mt8186_mutex_driver_data = { 406 .mutex_mod = mt8186_mutex_mod, 407 .mutex_sof = mt8186_mutex_sof, 408 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 409 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 410 }; 411 412 static const struct mtk_mutex_data mt8192_mutex_driver_data = { 413 .mutex_mod = mt8192_mutex_mod, 414 .mutex_sof = mt8183_mutex_sof, 415 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 416 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 417 }; 418 419 static const struct mtk_mutex_data mt8195_mutex_driver_data = { 420 .mutex_mod = mt8195_mutex_mod, 421 .mutex_sof = mt8195_mutex_sof, 422 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 423 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 424 }; 425 426 struct mtk_mutex *mtk_mutex_get(struct device *dev) 427 { 428 struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev); 429 int i; 430 431 for (i = 0; i < 10; i++) 432 if (!mtx->mutex[i].claimed) { 433 mtx->mutex[i].claimed = true; 434 return &mtx->mutex[i]; 435 } 436 437 return ERR_PTR(-EBUSY); 438 } 439 EXPORT_SYMBOL_GPL(mtk_mutex_get); 440 441 void mtk_mutex_put(struct mtk_mutex *mutex) 442 { 443 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 444 mutex[mutex->id]); 445 446 WARN_ON(&mtx->mutex[mutex->id] != mutex); 447 448 mutex->claimed = false; 449 } 450 EXPORT_SYMBOL_GPL(mtk_mutex_put); 451 452 int mtk_mutex_prepare(struct mtk_mutex *mutex) 453 { 454 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 455 mutex[mutex->id]); 456 return clk_prepare_enable(mtx->clk); 457 } 458 EXPORT_SYMBOL_GPL(mtk_mutex_prepare); 459 460 void mtk_mutex_unprepare(struct mtk_mutex *mutex) 461 { 462 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 463 mutex[mutex->id]); 464 clk_disable_unprepare(mtx->clk); 465 } 466 EXPORT_SYMBOL_GPL(mtk_mutex_unprepare); 467 468 void mtk_mutex_add_comp(struct mtk_mutex *mutex, 469 enum mtk_ddp_comp_id id) 470 { 471 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 472 mutex[mutex->id]); 473 unsigned int reg; 474 unsigned int sof_id; 475 unsigned int offset; 476 477 WARN_ON(&mtx->mutex[mutex->id] != mutex); 478 479 switch (id) { 480 case DDP_COMPONENT_DSI0: 481 sof_id = MUTEX_SOF_DSI0; 482 break; 483 case DDP_COMPONENT_DSI1: 484 sof_id = MUTEX_SOF_DSI0; 485 break; 486 case DDP_COMPONENT_DSI2: 487 sof_id = MUTEX_SOF_DSI2; 488 break; 489 case DDP_COMPONENT_DSI3: 490 sof_id = MUTEX_SOF_DSI3; 491 break; 492 case DDP_COMPONENT_DPI0: 493 sof_id = MUTEX_SOF_DPI0; 494 break; 495 case DDP_COMPONENT_DPI1: 496 sof_id = MUTEX_SOF_DPI1; 497 break; 498 case DDP_COMPONENT_DP_INTF0: 499 sof_id = MUTEX_SOF_DP_INTF0; 500 break; 501 default: 502 if (mtx->data->mutex_mod[id] < 32) { 503 offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 504 mutex->id); 505 reg = readl_relaxed(mtx->regs + offset); 506 reg |= 1 << mtx->data->mutex_mod[id]; 507 writel_relaxed(reg, mtx->regs + offset); 508 } else { 509 offset = DISP_REG_MUTEX_MOD2(mutex->id); 510 reg = readl_relaxed(mtx->regs + offset); 511 reg |= 1 << (mtx->data->mutex_mod[id] - 32); 512 writel_relaxed(reg, mtx->regs + offset); 513 } 514 return; 515 } 516 517 writel_relaxed(mtx->data->mutex_sof[sof_id], 518 mtx->regs + 519 DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id)); 520 } 521 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp); 522 523 void mtk_mutex_remove_comp(struct mtk_mutex *mutex, 524 enum mtk_ddp_comp_id id) 525 { 526 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 527 mutex[mutex->id]); 528 unsigned int reg; 529 unsigned int offset; 530 531 WARN_ON(&mtx->mutex[mutex->id] != mutex); 532 533 switch (id) { 534 case DDP_COMPONENT_DSI0: 535 case DDP_COMPONENT_DSI1: 536 case DDP_COMPONENT_DSI2: 537 case DDP_COMPONENT_DSI3: 538 case DDP_COMPONENT_DPI0: 539 case DDP_COMPONENT_DPI1: 540 case DDP_COMPONENT_DP_INTF0: 541 writel_relaxed(MUTEX_SOF_SINGLE_MODE, 542 mtx->regs + 543 DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, 544 mutex->id)); 545 break; 546 default: 547 if (mtx->data->mutex_mod[id] < 32) { 548 offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 549 mutex->id); 550 reg = readl_relaxed(mtx->regs + offset); 551 reg &= ~(1 << mtx->data->mutex_mod[id]); 552 writel_relaxed(reg, mtx->regs + offset); 553 } else { 554 offset = DISP_REG_MUTEX_MOD2(mutex->id); 555 reg = readl_relaxed(mtx->regs + offset); 556 reg &= ~(1 << (mtx->data->mutex_mod[id] - 32)); 557 writel_relaxed(reg, mtx->regs + offset); 558 } 559 break; 560 } 561 } 562 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp); 563 564 void mtk_mutex_enable(struct mtk_mutex *mutex) 565 { 566 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 567 mutex[mutex->id]); 568 569 WARN_ON(&mtx->mutex[mutex->id] != mutex); 570 571 writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 572 } 573 EXPORT_SYMBOL_GPL(mtk_mutex_enable); 574 575 void mtk_mutex_disable(struct mtk_mutex *mutex) 576 { 577 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 578 mutex[mutex->id]); 579 580 WARN_ON(&mtx->mutex[mutex->id] != mutex); 581 582 writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 583 } 584 EXPORT_SYMBOL_GPL(mtk_mutex_disable); 585 586 void mtk_mutex_acquire(struct mtk_mutex *mutex) 587 { 588 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 589 mutex[mutex->id]); 590 u32 tmp; 591 592 writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 593 writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id)); 594 if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id), 595 tmp, tmp & INT_MUTEX, 1, 10000)) 596 pr_err("could not acquire mutex %d\n", mutex->id); 597 } 598 EXPORT_SYMBOL_GPL(mtk_mutex_acquire); 599 600 void mtk_mutex_release(struct mtk_mutex *mutex) 601 { 602 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 603 mutex[mutex->id]); 604 605 writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id)); 606 } 607 EXPORT_SYMBOL_GPL(mtk_mutex_release); 608 609 static int mtk_mutex_probe(struct platform_device *pdev) 610 { 611 struct device *dev = &pdev->dev; 612 struct mtk_mutex_ctx *mtx; 613 struct resource *regs; 614 int i; 615 616 mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); 617 if (!mtx) 618 return -ENOMEM; 619 620 for (i = 0; i < 10; i++) 621 mtx->mutex[i].id = i; 622 623 mtx->data = of_device_get_match_data(dev); 624 625 if (!mtx->data->no_clk) { 626 mtx->clk = devm_clk_get(dev, NULL); 627 if (IS_ERR(mtx->clk)) { 628 if (PTR_ERR(mtx->clk) != -EPROBE_DEFER) 629 dev_err(dev, "Failed to get clock\n"); 630 return PTR_ERR(mtx->clk); 631 } 632 } 633 634 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 635 mtx->regs = devm_ioremap_resource(dev, regs); 636 if (IS_ERR(mtx->regs)) { 637 dev_err(dev, "Failed to map mutex registers\n"); 638 return PTR_ERR(mtx->regs); 639 } 640 641 platform_set_drvdata(pdev, mtx); 642 643 return 0; 644 } 645 646 static int mtk_mutex_remove(struct platform_device *pdev) 647 { 648 return 0; 649 } 650 651 static const struct of_device_id mutex_driver_dt_match[] = { 652 { .compatible = "mediatek,mt2701-disp-mutex", 653 .data = &mt2701_mutex_driver_data}, 654 { .compatible = "mediatek,mt2712-disp-mutex", 655 .data = &mt2712_mutex_driver_data}, 656 { .compatible = "mediatek,mt8167-disp-mutex", 657 .data = &mt8167_mutex_driver_data}, 658 { .compatible = "mediatek,mt8173-disp-mutex", 659 .data = &mt8173_mutex_driver_data}, 660 { .compatible = "mediatek,mt8183-disp-mutex", 661 .data = &mt8183_mutex_driver_data}, 662 { .compatible = "mediatek,mt8186-disp-mutex", 663 .data = &mt8186_mutex_driver_data}, 664 { .compatible = "mediatek,mt8192-disp-mutex", 665 .data = &mt8192_mutex_driver_data}, 666 { .compatible = "mediatek,mt8195-disp-mutex", 667 .data = &mt8195_mutex_driver_data}, 668 {}, 669 }; 670 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match); 671 672 static struct platform_driver mtk_mutex_driver = { 673 .probe = mtk_mutex_probe, 674 .remove = mtk_mutex_remove, 675 .driver = { 676 .name = "mediatek-mutex", 677 .owner = THIS_MODULE, 678 .of_match_table = mutex_driver_dt_match, 679 }, 680 }; 681 682 builtin_platform_driver(mtk_mutex_driver); 683