Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.5-rc1 672 lines 22 kB view raw
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 13#include "mtk_drm_ddp.h" 14#include "mtk_drm_ddp_comp.h" 15 16#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x040 17#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN 0x044 18#define DISP_REG_CONFIG_DISP_OD_MOUT_EN 0x048 19#define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN 0x04c 20#define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN 0x050 21#define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN 0x084 22#define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN 0x088 23#define DISP_REG_CONFIG_DSIE_SEL_IN 0x0a4 24#define DISP_REG_CONFIG_DSIO_SEL_IN 0x0a8 25#define DISP_REG_CONFIG_DPI_SEL_IN 0x0ac 26#define DISP_REG_CONFIG_DISP_RDMA2_SOUT 0x0b8 27#define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN 0x0c4 28#define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN 0x0c8 29#define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100 30 31#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030 32#define DISP_REG_CONFIG_OUT_SEL 0x04c 33#define DISP_REG_CONFIG_DSI_SEL 0x050 34#define DISP_REG_CONFIG_DPI_SEL 0x064 35 36#define MT2701_DISP_MUTEX0_MOD0 0x2c 37#define MT2701_DISP_MUTEX0_SOF0 0x30 38 39#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 40#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 41#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 42#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 43#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 44#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 45 46#define INT_MUTEX BIT(1) 47 48#define MT8173_MUTEX_MOD_DISP_OVL0 11 49#define MT8173_MUTEX_MOD_DISP_OVL1 12 50#define MT8173_MUTEX_MOD_DISP_RDMA0 13 51#define MT8173_MUTEX_MOD_DISP_RDMA1 14 52#define MT8173_MUTEX_MOD_DISP_RDMA2 15 53#define MT8173_MUTEX_MOD_DISP_WDMA0 16 54#define MT8173_MUTEX_MOD_DISP_WDMA1 17 55#define MT8173_MUTEX_MOD_DISP_COLOR0 18 56#define MT8173_MUTEX_MOD_DISP_COLOR1 19 57#define MT8173_MUTEX_MOD_DISP_AAL 20 58#define MT8173_MUTEX_MOD_DISP_GAMMA 21 59#define MT8173_MUTEX_MOD_DISP_UFOE 22 60#define MT8173_MUTEX_MOD_DISP_PWM0 23 61#define MT8173_MUTEX_MOD_DISP_PWM1 24 62#define MT8173_MUTEX_MOD_DISP_OD 25 63 64#define MT2712_MUTEX_MOD_DISP_PWM2 10 65#define MT2712_MUTEX_MOD_DISP_OVL0 11 66#define MT2712_MUTEX_MOD_DISP_OVL1 12 67#define MT2712_MUTEX_MOD_DISP_RDMA0 13 68#define MT2712_MUTEX_MOD_DISP_RDMA1 14 69#define MT2712_MUTEX_MOD_DISP_RDMA2 15 70#define MT2712_MUTEX_MOD_DISP_WDMA0 16 71#define MT2712_MUTEX_MOD_DISP_WDMA1 17 72#define MT2712_MUTEX_MOD_DISP_COLOR0 18 73#define MT2712_MUTEX_MOD_DISP_COLOR1 19 74#define MT2712_MUTEX_MOD_DISP_AAL0 20 75#define MT2712_MUTEX_MOD_DISP_UFOE 22 76#define MT2712_MUTEX_MOD_DISP_PWM0 23 77#define MT2712_MUTEX_MOD_DISP_PWM1 24 78#define MT2712_MUTEX_MOD_DISP_OD0 25 79#define MT2712_MUTEX_MOD2_DISP_AAL1 33 80#define MT2712_MUTEX_MOD2_DISP_OD1 34 81 82#define MT2701_MUTEX_MOD_DISP_OVL 3 83#define MT2701_MUTEX_MOD_DISP_WDMA 6 84#define MT2701_MUTEX_MOD_DISP_COLOR 7 85#define MT2701_MUTEX_MOD_DISP_BLS 9 86#define MT2701_MUTEX_MOD_DISP_RDMA0 10 87#define MT2701_MUTEX_MOD_DISP_RDMA1 12 88 89#define MUTEX_SOF_SINGLE_MODE 0 90#define MUTEX_SOF_DSI0 1 91#define MUTEX_SOF_DSI1 2 92#define MUTEX_SOF_DPI0 3 93#define MUTEX_SOF_DPI1 4 94#define MUTEX_SOF_DSI2 5 95#define MUTEX_SOF_DSI3 6 96 97#define OVL0_MOUT_EN_COLOR0 0x1 98#define OD_MOUT_EN_RDMA0 0x1 99#define OD1_MOUT_EN_RDMA1 BIT(16) 100#define UFOE_MOUT_EN_DSI0 0x1 101#define COLOR0_SEL_IN_OVL0 0x1 102#define OVL1_MOUT_EN_COLOR1 0x1 103#define GAMMA_MOUT_EN_RDMA1 0x1 104#define RDMA0_SOUT_DPI0 0x2 105#define RDMA0_SOUT_DPI1 0x3 106#define RDMA0_SOUT_DSI1 0x1 107#define RDMA0_SOUT_DSI2 0x4 108#define RDMA0_SOUT_DSI3 0x5 109#define RDMA1_SOUT_DPI0 0x2 110#define RDMA1_SOUT_DPI1 0x3 111#define RDMA1_SOUT_DSI1 0x1 112#define RDMA1_SOUT_DSI2 0x4 113#define RDMA1_SOUT_DSI3 0x5 114#define RDMA2_SOUT_DPI0 0x2 115#define RDMA2_SOUT_DPI1 0x3 116#define RDMA2_SOUT_DSI1 0x1 117#define RDMA2_SOUT_DSI2 0x4 118#define RDMA2_SOUT_DSI3 0x5 119#define DPI0_SEL_IN_RDMA1 0x1 120#define DPI0_SEL_IN_RDMA2 0x3 121#define DPI1_SEL_IN_RDMA1 (0x1 << 8) 122#define DPI1_SEL_IN_RDMA2 (0x3 << 8) 123#define DSI0_SEL_IN_RDMA1 0x1 124#define DSI0_SEL_IN_RDMA2 0x4 125#define DSI1_SEL_IN_RDMA1 0x1 126#define DSI1_SEL_IN_RDMA2 0x4 127#define DSI2_SEL_IN_RDMA1 (0x1 << 16) 128#define DSI2_SEL_IN_RDMA2 (0x4 << 16) 129#define DSI3_SEL_IN_RDMA1 (0x1 << 16) 130#define DSI3_SEL_IN_RDMA2 (0x4 << 16) 131#define COLOR1_SEL_IN_OVL1 0x1 132 133#define OVL_MOUT_EN_RDMA 0x1 134#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8 135#define BLS_TO_DPI_RDMA1_TO_DSI 0x2 136#define DSI_SEL_IN_BLS 0x0 137#define DPI_SEL_IN_BLS 0x0 138#define DSI_SEL_IN_RDMA 0x1 139 140struct mtk_disp_mutex { 141 int id; 142 bool claimed; 143}; 144 145enum mtk_ddp_mutex_sof_id { 146 DDP_MUTEX_SOF_SINGLE_MODE, 147 DDP_MUTEX_SOF_DSI0, 148 DDP_MUTEX_SOF_DSI1, 149 DDP_MUTEX_SOF_DPI0, 150 DDP_MUTEX_SOF_DPI1, 151 DDP_MUTEX_SOF_DSI2, 152 DDP_MUTEX_SOF_DSI3, 153}; 154 155struct mtk_ddp_data { 156 const unsigned int *mutex_mod; 157 const unsigned int *mutex_sof; 158 const unsigned int mutex_mod_reg; 159 const unsigned int mutex_sof_reg; 160 const bool no_clk; 161}; 162 163struct mtk_ddp { 164 struct device *dev; 165 struct clk *clk; 166 void __iomem *regs; 167 struct mtk_disp_mutex mutex[10]; 168 const struct mtk_ddp_data *data; 169}; 170 171static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { 172 [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS, 173 [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR, 174 [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL, 175 [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0, 176 [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1, 177 [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA, 178}; 179 180static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { 181 [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0, 182 [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1, 183 [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0, 184 [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1, 185 [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0, 186 [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1, 187 [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0, 188 [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1, 189 [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0, 190 [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1, 191 [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2, 192 [DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0, 193 [DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1, 194 [DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2, 195 [DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE, 196 [DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0, 197 [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1, 198}; 199 200static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = { 201 [DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL, 202 [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0, 203 [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1, 204 [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA, 205 [DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD, 206 [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0, 207 [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1, 208 [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0, 209 [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1, 210 [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0, 211 [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1, 212 [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2, 213 [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE, 214 [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0, 215 [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1, 216}; 217 218static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = { 219 [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 220 [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 221 [DDP_MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, 222 [DDP_MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, 223 [DDP_MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1, 224 [DDP_MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2, 225 [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, 226}; 227 228static const struct mtk_ddp_data mt2701_ddp_driver_data = { 229 .mutex_mod = mt2701_mutex_mod, 230 .mutex_sof = mt2712_mutex_sof, 231 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 232 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 233}; 234 235static const struct mtk_ddp_data mt2712_ddp_driver_data = { 236 .mutex_mod = mt2712_mutex_mod, 237 .mutex_sof = mt2712_mutex_sof, 238 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 239 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 240}; 241 242static const struct mtk_ddp_data mt8173_ddp_driver_data = { 243 .mutex_mod = mt8173_mutex_mod, 244 .mutex_sof = mt2712_mutex_sof, 245 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 246 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 247}; 248 249static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur, 250 enum mtk_ddp_comp_id next, 251 unsigned int *addr) 252{ 253 unsigned int value; 254 255 if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) { 256 *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN; 257 value = OVL0_MOUT_EN_COLOR0; 258 } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) { 259 *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN; 260 value = OVL_MOUT_EN_RDMA; 261 } else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) { 262 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN; 263 value = OD_MOUT_EN_RDMA0; 264 } else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) { 265 *addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN; 266 value = UFOE_MOUT_EN_DSI0; 267 } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) { 268 *addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN; 269 value = OVL1_MOUT_EN_COLOR1; 270 } else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) { 271 *addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN; 272 value = GAMMA_MOUT_EN_RDMA1; 273 } else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) { 274 *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN; 275 value = OD1_MOUT_EN_RDMA1; 276 } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) { 277 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; 278 value = RDMA0_SOUT_DPI0; 279 } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) { 280 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; 281 value = RDMA0_SOUT_DPI1; 282 } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) { 283 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; 284 value = RDMA0_SOUT_DSI1; 285 } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) { 286 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; 287 value = RDMA0_SOUT_DSI2; 288 } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) { 289 *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; 290 value = RDMA0_SOUT_DSI3; 291 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) { 292 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN; 293 value = RDMA1_SOUT_DSI1; 294 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) { 295 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN; 296 value = RDMA1_SOUT_DSI2; 297 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) { 298 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN; 299 value = RDMA1_SOUT_DSI3; 300 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) { 301 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN; 302 value = RDMA1_SOUT_DPI0; 303 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) { 304 *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN; 305 value = RDMA1_SOUT_DPI1; 306 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) { 307 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT; 308 value = RDMA2_SOUT_DPI0; 309 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) { 310 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT; 311 value = RDMA2_SOUT_DPI1; 312 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) { 313 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT; 314 value = RDMA2_SOUT_DSI1; 315 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) { 316 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT; 317 value = RDMA2_SOUT_DSI2; 318 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) { 319 *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT; 320 value = RDMA2_SOUT_DSI3; 321 } else { 322 value = 0; 323 } 324 325 return value; 326} 327 328static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur, 329 enum mtk_ddp_comp_id next, 330 unsigned int *addr) 331{ 332 unsigned int value; 333 334 if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) { 335 *addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN; 336 value = COLOR0_SEL_IN_OVL0; 337 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) { 338 *addr = DISP_REG_CONFIG_DPI_SEL_IN; 339 value = DPI0_SEL_IN_RDMA1; 340 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) { 341 *addr = DISP_REG_CONFIG_DPI_SEL_IN; 342 value = DPI1_SEL_IN_RDMA1; 343 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) { 344 *addr = DISP_REG_CONFIG_DSIE_SEL_IN; 345 value = DSI0_SEL_IN_RDMA1; 346 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) { 347 *addr = DISP_REG_CONFIG_DSIO_SEL_IN; 348 value = DSI1_SEL_IN_RDMA1; 349 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) { 350 *addr = DISP_REG_CONFIG_DSIE_SEL_IN; 351 value = DSI2_SEL_IN_RDMA1; 352 } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) { 353 *addr = DISP_REG_CONFIG_DSIO_SEL_IN; 354 value = DSI3_SEL_IN_RDMA1; 355 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) { 356 *addr = DISP_REG_CONFIG_DPI_SEL_IN; 357 value = DPI0_SEL_IN_RDMA2; 358 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) { 359 *addr = DISP_REG_CONFIG_DPI_SEL_IN; 360 value = DPI1_SEL_IN_RDMA2; 361 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) { 362 *addr = DISP_REG_CONFIG_DSIE_SEL_IN; 363 value = DSI0_SEL_IN_RDMA2; 364 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) { 365 *addr = DISP_REG_CONFIG_DSIO_SEL_IN; 366 value = DSI1_SEL_IN_RDMA2; 367 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) { 368 *addr = DISP_REG_CONFIG_DSIE_SEL_IN; 369 value = DSI2_SEL_IN_RDMA2; 370 } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) { 371 *addr = DISP_REG_CONFIG_DSIE_SEL_IN; 372 value = DSI3_SEL_IN_RDMA2; 373 } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) { 374 *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN; 375 value = COLOR1_SEL_IN_OVL1; 376 } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) { 377 *addr = DISP_REG_CONFIG_DSI_SEL; 378 value = DSI_SEL_IN_BLS; 379 } else { 380 value = 0; 381 } 382 383 return value; 384} 385 386static void mtk_ddp_sout_sel(void __iomem *config_regs, 387 enum mtk_ddp_comp_id cur, 388 enum mtk_ddp_comp_id next) 389{ 390 if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) { 391 writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1, 392 config_regs + DISP_REG_CONFIG_OUT_SEL); 393 } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) { 394 writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI, 395 config_regs + DISP_REG_CONFIG_OUT_SEL); 396 writel_relaxed(DSI_SEL_IN_RDMA, 397 config_regs + DISP_REG_CONFIG_DSI_SEL); 398 writel_relaxed(DPI_SEL_IN_BLS, 399 config_regs + DISP_REG_CONFIG_DPI_SEL); 400 } 401} 402 403void mtk_ddp_add_comp_to_path(void __iomem *config_regs, 404 enum mtk_ddp_comp_id cur, 405 enum mtk_ddp_comp_id next) 406{ 407 unsigned int addr, value, reg; 408 409 value = mtk_ddp_mout_en(cur, next, &addr); 410 if (value) { 411 reg = readl_relaxed(config_regs + addr) | value; 412 writel_relaxed(reg, config_regs + addr); 413 } 414 415 mtk_ddp_sout_sel(config_regs, cur, next); 416 417 value = mtk_ddp_sel_in(cur, next, &addr); 418 if (value) { 419 reg = readl_relaxed(config_regs + addr) | value; 420 writel_relaxed(reg, config_regs + addr); 421 } 422} 423 424void mtk_ddp_remove_comp_from_path(void __iomem *config_regs, 425 enum mtk_ddp_comp_id cur, 426 enum mtk_ddp_comp_id next) 427{ 428 unsigned int addr, value, reg; 429 430 value = mtk_ddp_mout_en(cur, next, &addr); 431 if (value) { 432 reg = readl_relaxed(config_regs + addr) & ~value; 433 writel_relaxed(reg, config_regs + addr); 434 } 435 436 value = mtk_ddp_sel_in(cur, next, &addr); 437 if (value) { 438 reg = readl_relaxed(config_regs + addr) & ~value; 439 writel_relaxed(reg, config_regs + addr); 440 } 441} 442 443struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id) 444{ 445 struct mtk_ddp *ddp = dev_get_drvdata(dev); 446 447 if (id >= 10) 448 return ERR_PTR(-EINVAL); 449 if (ddp->mutex[id].claimed) 450 return ERR_PTR(-EBUSY); 451 452 ddp->mutex[id].claimed = true; 453 454 return &ddp->mutex[id]; 455} 456 457void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex) 458{ 459 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 460 mutex[mutex->id]); 461 462 WARN_ON(&ddp->mutex[mutex->id] != mutex); 463 464 mutex->claimed = false; 465} 466 467int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex) 468{ 469 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 470 mutex[mutex->id]); 471 return clk_prepare_enable(ddp->clk); 472} 473 474void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex) 475{ 476 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 477 mutex[mutex->id]); 478 clk_disable_unprepare(ddp->clk); 479} 480 481void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex, 482 enum mtk_ddp_comp_id id) 483{ 484 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 485 mutex[mutex->id]); 486 unsigned int reg; 487 unsigned int sof_id; 488 unsigned int offset; 489 490 WARN_ON(&ddp->mutex[mutex->id] != mutex); 491 492 switch (id) { 493 case DDP_COMPONENT_DSI0: 494 sof_id = DDP_MUTEX_SOF_DSI0; 495 break; 496 case DDP_COMPONENT_DSI1: 497 sof_id = DDP_MUTEX_SOF_DSI0; 498 break; 499 case DDP_COMPONENT_DSI2: 500 sof_id = DDP_MUTEX_SOF_DSI2; 501 break; 502 case DDP_COMPONENT_DSI3: 503 sof_id = DDP_MUTEX_SOF_DSI3; 504 break; 505 case DDP_COMPONENT_DPI0: 506 sof_id = DDP_MUTEX_SOF_DPI0; 507 break; 508 case DDP_COMPONENT_DPI1: 509 sof_id = DDP_MUTEX_SOF_DPI1; 510 break; 511 default: 512 if (ddp->data->mutex_mod[id] < 32) { 513 offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 514 mutex->id); 515 reg = readl_relaxed(ddp->regs + offset); 516 reg |= 1 << ddp->data->mutex_mod[id]; 517 writel_relaxed(reg, ddp->regs + offset); 518 } else { 519 offset = DISP_REG_MUTEX_MOD2(mutex->id); 520 reg = readl_relaxed(ddp->regs + offset); 521 reg |= 1 << (ddp->data->mutex_mod[id] - 32); 522 writel_relaxed(reg, ddp->regs + offset); 523 } 524 return; 525 } 526 527 writel_relaxed(ddp->data->mutex_sof[sof_id], 528 ddp->regs + 529 DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, mutex->id)); 530} 531 532void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, 533 enum mtk_ddp_comp_id id) 534{ 535 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 536 mutex[mutex->id]); 537 unsigned int reg; 538 unsigned int offset; 539 540 WARN_ON(&ddp->mutex[mutex->id] != mutex); 541 542 switch (id) { 543 case DDP_COMPONENT_DSI0: 544 case DDP_COMPONENT_DSI1: 545 case DDP_COMPONENT_DSI2: 546 case DDP_COMPONENT_DSI3: 547 case DDP_COMPONENT_DPI0: 548 case DDP_COMPONENT_DPI1: 549 writel_relaxed(MUTEX_SOF_SINGLE_MODE, 550 ddp->regs + 551 DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, 552 mutex->id)); 553 break; 554 default: 555 if (ddp->data->mutex_mod[id] < 32) { 556 offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 557 mutex->id); 558 reg = readl_relaxed(ddp->regs + offset); 559 reg &= ~(1 << ddp->data->mutex_mod[id]); 560 writel_relaxed(reg, ddp->regs + offset); 561 } else { 562 offset = DISP_REG_MUTEX_MOD2(mutex->id); 563 reg = readl_relaxed(ddp->regs + offset); 564 reg &= ~(1 << (ddp->data->mutex_mod[id] - 32)); 565 writel_relaxed(reg, ddp->regs + offset); 566 } 567 break; 568 } 569} 570 571void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex) 572{ 573 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 574 mutex[mutex->id]); 575 576 WARN_ON(&ddp->mutex[mutex->id] != mutex); 577 578 writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 579} 580 581void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex) 582{ 583 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 584 mutex[mutex->id]); 585 586 WARN_ON(&ddp->mutex[mutex->id] != mutex); 587 588 writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 589} 590 591void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex) 592{ 593 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 594 mutex[mutex->id]); 595 u32 tmp; 596 597 writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 598 writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id)); 599 if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id), 600 tmp, tmp & INT_MUTEX, 1, 10000)) 601 pr_err("could not acquire mutex %d\n", mutex->id); 602} 603 604void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex) 605{ 606 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 607 mutex[mutex->id]); 608 609 writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id)); 610} 611 612static int mtk_ddp_probe(struct platform_device *pdev) 613{ 614 struct device *dev = &pdev->dev; 615 struct mtk_ddp *ddp; 616 struct resource *regs; 617 int i; 618 619 ddp = devm_kzalloc(dev, sizeof(*ddp), GFP_KERNEL); 620 if (!ddp) 621 return -ENOMEM; 622 623 for (i = 0; i < 10; i++) 624 ddp->mutex[i].id = i; 625 626 ddp->data = of_device_get_match_data(dev); 627 628 if (!ddp->data->no_clk) { 629 ddp->clk = devm_clk_get(dev, NULL); 630 if (IS_ERR(ddp->clk)) { 631 dev_err(dev, "Failed to get clock\n"); 632 return PTR_ERR(ddp->clk); 633 } 634 } 635 636 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 637 ddp->regs = devm_ioremap_resource(dev, regs); 638 if (IS_ERR(ddp->regs)) { 639 dev_err(dev, "Failed to map mutex registers\n"); 640 return PTR_ERR(ddp->regs); 641 } 642 643 platform_set_drvdata(pdev, ddp); 644 645 return 0; 646} 647 648static int mtk_ddp_remove(struct platform_device *pdev) 649{ 650 return 0; 651} 652 653static const struct of_device_id ddp_driver_dt_match[] = { 654 { .compatible = "mediatek,mt2701-disp-mutex", 655 .data = &mt2701_ddp_driver_data}, 656 { .compatible = "mediatek,mt2712-disp-mutex", 657 .data = &mt2712_ddp_driver_data}, 658 { .compatible = "mediatek,mt8173-disp-mutex", 659 .data = &mt8173_ddp_driver_data}, 660 {}, 661}; 662MODULE_DEVICE_TABLE(of, ddp_driver_dt_match); 663 664struct platform_driver mtk_ddp_driver = { 665 .probe = mtk_ddp_probe, 666 .remove = mtk_ddp_remove, 667 .driver = { 668 .name = "mediatek-ddp", 669 .owner = THIS_MODULE, 670 .of_match_table = ddp_driver_dt_match, 671 }, 672};