mtk-mutex.c (22825B)
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 165struct mtk_mutex { 166 int id; 167 bool claimed; 168}; 169 170enum 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 183struct 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 191struct 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 199static 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 208static 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 228static 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 243static 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 261static 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 275static 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 288static 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 302static 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 318static 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 328static 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 */ 336static 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 342static 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 */ 356static 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 368static 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 375static 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 382static 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 390static 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 397static 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 405static 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 412static 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 419static 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 426struct 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} 439EXPORT_SYMBOL_GPL(mtk_mutex_get); 440 441void 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} 450EXPORT_SYMBOL_GPL(mtk_mutex_put); 451 452int 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} 458EXPORT_SYMBOL_GPL(mtk_mutex_prepare); 459 460void 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} 466EXPORT_SYMBOL_GPL(mtk_mutex_unprepare); 467 468void 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} 521EXPORT_SYMBOL_GPL(mtk_mutex_add_comp); 522 523void 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} 562EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp); 563 564void 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} 573EXPORT_SYMBOL_GPL(mtk_mutex_enable); 574 575void 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} 584EXPORT_SYMBOL_GPL(mtk_mutex_disable); 585 586void 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} 598EXPORT_SYMBOL_GPL(mtk_mutex_acquire); 599 600void 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} 607EXPORT_SYMBOL_GPL(mtk_mutex_release); 608 609static 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 646static int mtk_mutex_remove(struct platform_device *pdev) 647{ 648 return 0; 649} 650 651static 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}; 670MODULE_DEVICE_TABLE(of, mutex_driver_dt_match); 671 672static 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 682builtin_platform_driver(mtk_mutex_driver);