File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_lcdifv2.h"
0010
0011
0012
0013
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.lcdifv2"
0018 #endif
0019
0020 #define LCDIFV2_LUT_MEM(base) \
0021 ((volatile uint32_t *)(((uint32_t)(base)) + (uint32_t)FSL_FEATURE_LCDIFV2_CLUT_RAM_OFFSET))
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base);
0033
0034
0035
0036
0037
0038
0039 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base);
0040
0041
0042
0043
0044
0045 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0046
0047 static const clock_ip_name_t s_lcdifv2Clocks[] = LCDIFV2_CLOCKS;
0048 #endif
0049
0050
0051
0052
0053 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base)
0054 {
0055 static LCDIFV2_Type *const s_lcdifv2Bases[] = LCDIFV2_BASE_PTRS;
0056
0057 uint32_t instance;
0058
0059
0060 for (instance = 0; instance < ARRAY_SIZE(s_lcdifv2Bases); instance++)
0061 {
0062 if (s_lcdifv2Bases[instance] == base)
0063 {
0064 break;
0065 }
0066 }
0067
0068 assert(instance < ARRAY_SIZE(s_lcdifv2Bases));
0069
0070 return instance;
0071 }
0072
0073 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base)
0074 {
0075 uint32_t i;
0076
0077 base->DISP_PARA = 0U;
0078 base->CTRL = 0x80000000U;
0079 base->DISP_SIZE = 0U;
0080 base->HSYN_PARA = 0x00C01803U;
0081 base->VSYN_PARA = 0x00C01803U;
0082 base->INT[0].INT_ENABLE = 0U;
0083 base->INT[1].INT_ENABLE = 0U;
0084 base->PDI_PARA = 0x00001000U;
0085
0086 for (i = 0; i < (uint32_t)LCDIFV2_LAYER_COUNT; i++)
0087 {
0088 base->LAYER[i].CTRLDESCL5 = 0U;
0089 base->LAYER[i].CTRLDESCL1 = 0U;
0090 base->LAYER[i].CTRLDESCL2 = 0U;
0091 base->LAYER[i].CTRLDESCL3 = 0U;
0092 base->LAYER[i].CTRLDESCL4 = 0U;
0093 base->LAYER[i].CTRLDESCL6 = 0U;
0094 }
0095
0096 for (i = 0; i < (uint32_t)LCDIFV2_LAYER_CSC_COUNT; i++)
0097 {
0098 base->LAYER[i].CSC_COEF0 = 0x04000000U;
0099 base->LAYER[i].CSC_COEF1 = 0x01230208U;
0100 base->LAYER[i].CSC_COEF2 = 0x076B079CU;
0101 }
0102
0103
0104 base->INT[0].INT_STATUS = 0xFFFFFFFFU;
0105 base->INT[1].INT_STATUS = 0xFFFFFFFFU;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115 void LCDIFV2_Init(LCDIFV2_Type *base)
0116 {
0117 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0118 uint32_t instance = LCDIFV2_GetInstance(base);
0119
0120 CLOCK_EnableClock(s_lcdifv2Clocks[instance]);
0121 #endif
0122
0123 LCDIFV2_ResetRegister(base);
0124
0125
0126 base->CTRL = 0U;
0127 }
0128
0129
0130
0131
0132
0133
0134 void LCDIFV2_Deinit(LCDIFV2_Type *base)
0135 {
0136 LCDIFV2_ResetRegister(base);
0137
0138 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0139 uint32_t instance = LCDIFV2_GetInstance(base);
0140
0141 CLOCK_DisableClock(s_lcdifv2Clocks[instance]);
0142 #endif
0143 }
0144
0145
0146
0147
0148
0149
0150 void LCDIFV2_Reset(LCDIFV2_Type *base)
0151 {
0152 LCDIFV2_ResetRegister(base);
0153
0154
0155 base->CTRL = 0U;
0156 }
0157
0158
0159
0160
0161
0162
0163 void LCDIFV2_DisplayGetDefaultConfig(lcdifv2_display_config_t *config)
0164 {
0165 assert(NULL != config);
0166
0167 config->panelWidth = 0U;
0168 config->panelHeight = 0U;
0169 config->hsw = 3U;
0170 config->hfp = 3U;
0171 config->hbp = 3U;
0172 config->vsw = 3U;
0173 config->vfp = 3U;
0174 config->vbp = 3U;
0175 config->polarityFlags = (uint32_t)kLCDIFV2_VsyncActiveHigh | (uint32_t)kLCDIFV2_HsyncActiveHigh |
0176 (uint32_t)kLCDIFV2_DataEnableActiveHigh | (uint32_t)kLCDIFV2_DriveDataOnRisingClkEdge |
0177 (uint32_t)kLCDIFV2_DataActiveHigh;
0178 config->lineOrder = kLCDIFV2_LineOrderRGB;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187 void LCDIFV2_SetDisplayConfig(LCDIFV2_Type *base, const lcdifv2_display_config_t *config)
0188 {
0189 assert(NULL != config);
0190
0191
0192 base->DISP_SIZE = ((uint32_t)config->panelWidth << LCDIFV2_DISP_SIZE_DELTA_X_SHIFT) |
0193 ((uint32_t)config->panelHeight << LCDIFV2_DISP_SIZE_DELTA_Y_SHIFT);
0194
0195 base->HSYN_PARA = ((uint32_t)config->hsw << LCDIFV2_HSYN_PARA_PW_H_SHIFT) |
0196 ((uint32_t)config->hbp << LCDIFV2_HSYN_PARA_BP_H_SHIFT) |
0197 ((uint32_t)config->hfp << LCDIFV2_HSYN_PARA_FP_H_SHIFT);
0198
0199 base->VSYN_PARA = ((uint32_t)config->vsw << LCDIFV2_VSYN_PARA_PW_V_SHIFT) |
0200 ((uint32_t)config->vbp << LCDIFV2_VSYN_PARA_BP_V_SHIFT) |
0201 ((uint32_t)config->vfp << LCDIFV2_VSYN_PARA_FP_V_SHIFT);
0202
0203 base->DISP_PARA = LCDIFV2_DISP_PARA_LINE_PATTERN((uint32_t)config->lineOrder);
0204
0205 base->CTRL = (uint32_t)(config->polarityFlags);
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 void LCDIFV2_SetCscMode(LCDIFV2_Type *base, uint8_t layerIndex, lcdifv2_csc_mode_t mode)
0218 {
0219 assert(layerIndex < (uint32_t)LCDIFV2_LAYER_CSC_COUNT);
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229 if (kLCDIFV2_CscYUV2RGB == mode)
0230 {
0231 base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_C0(0x100U)
0232 | LCDIFV2_CSC_COEF0_Y_OFFSET(0x0U)
0233 | LCDIFV2_CSC_COEF0_UV_OFFSET(0x0U);
0234
0235 base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0123U)
0236 | LCDIFV2_CSC_COEF1_C4(0x0208U);
0237 base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x076BU)
0238 | LCDIFV2_CSC_COEF2_C3(0x079BU);
0239 }
0240 else if (kLCDIFV2_CscYCbCr2RGB == mode)
0241 {
0242 base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_YCBCR_MODE_MASK |
0243 LCDIFV2_CSC_COEF0_C0(0x12AU)
0244 | LCDIFV2_CSC_COEF0_Y_OFFSET(0x1F0U)
0245 | LCDIFV2_CSC_COEF0_UV_OFFSET(0x180U);
0246 base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0198U)
0247 | LCDIFV2_CSC_COEF1_C4(0x0204U);
0248 base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x0730U)
0249 | LCDIFV2_CSC_COEF2_C3(0x079CU);
0250 }
0251 else
0252 {
0253 base->LAYER[layerIndex].CSC_COEF0 = 0U;
0254 base->LAYER[layerIndex].CSC_COEF1 = 0U;
0255 base->LAYER[layerIndex].CSC_COEF2 = 0U;
0256 }
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266 void LCDIFV2_SetLayerBufferConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_buffer_config_t *config)
0267 {
0268 assert(NULL != config);
0269 uint32_t reg;
0270
0271 base->LAYER[layerIndex].CTRLDESCL3 = config->strideBytes;
0272
0273 reg = base->LAYER[layerIndex].CTRLDESCL5;
0274 reg = (reg & ~(LCDIFV2_CTRLDESCL5_BPP_MASK | LCDIFV2_CTRLDESCL5_YUV_FORMAT_MASK)) | (uint32_t)config->pixelFormat;
0275
0276 if (0U == (reg & LCDIFV2_CTRLDESCL5_AB_MODE_MASK))
0277 {
0278 reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
0279 }
0280
0281 base->LAYER[layerIndex].CTRLDESCL5 = reg;
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 status_t LCDIFV2_SetLut(
0300 LCDIFV2_Type *base, uint8_t layerIndex, const uint32_t *lutData, uint16_t count, bool useShadowLoad)
0301 {
0302 assert(count <= LCDIFV2_LUT_ENTRY_NUM);
0303
0304 uint16_t i;
0305 status_t status;
0306
0307
0308 if ((base->CLUT_LOAD & LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK) != 0U)
0309 {
0310 status = kStatus_Fail;
0311 }
0312 else
0313 {
0314 if (useShadowLoad)
0315 {
0316 base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex) | LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK;
0317 }
0318 else
0319 {
0320 base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex);
0321 }
0322
0323 for (i = 0; i < count; i++)
0324 {
0325 (LCDIFV2_LUT_MEM(base))[i + (LCDIFV2_LUT_ENTRY_NUM * layerIndex)] = lutData[i];
0326 }
0327
0328 status = kStatus_Success;
0329 }
0330
0331 return status;
0332 }
0333
0334
0335
0336
0337
0338
0339
0340
0341 void LCDIFV2_SetLayerBlendConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_blend_config_t *config)
0342 {
0343 assert(NULL != config);
0344
0345 uint32_t reg;
0346
0347 reg = base->LAYER[layerIndex].CTRLDESCL5;
0348 reg &= ~(LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA_MASK | LCDIFV2_CTRLDESCL5_AB_MODE_MASK |
0349 LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE_MASK |
0350 LCDIFV2_CTRLDESCL5_PD_COLOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE_MASK |
0351 LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK);
0352
0353 reg |=
0354 (LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA(config->globalAlpha) | LCDIFV2_CTRLDESCL5_AB_MODE(config->alphaMode) |
0355 LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE(config->pdFactorMode) |
0356 LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE(config->pdAlphaMode) | LCDIFV2_CTRLDESCL5_PD_COLOR_MODE(config->pdColorMode) |
0357 LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE(config->pdGlobalAlphaMode));
0358
0359 if (config->alphaMode == kLCDIFV2_AlphaDisable)
0360 {
0361 reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
0362 }
0363
0364 base->LAYER[layerIndex].CTRLDESCL5 = reg;
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 status_t LCDIFV2_GetPorterDuffConfig(lcdifv2_pd_blend_mode_t mode,
0380 lcdifv2_pd_layer_t layer,
0381 lcdifv2_blend_config_t *config)
0382 {
0383 static const lcdifv2_pd_factor_mode_t s_lcdifv2PdLayerFactors[][2] = {
0384
0385 {
0386
0387 kLCDIFV2_PD_FactorZero,
0388
0389
0390 kLCDIFV2_PD_FactorOne,
0391 },
0392
0393
0394 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorStraightAlpha},
0395
0396
0397 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorOne},
0398
0399
0400 {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorStraightAlpha},
0401
0402
0403 {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorInversedAlpha},
0404
0405
0406 {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorZero},
0407
0408
0409 {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorInversedAlpha},
0410
0411
0412 {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorInversedAlpha},
0413
0414
0415 {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorZero},
0416
0417
0418 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorZero},
0419
0420
0421 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorInversedAlpha},
0422
0423
0424 {
0425 kLCDIFV2_PD_FactorZero,
0426 kLCDIFV2_PD_FactorZero,
0427 },
0428 };
0429
0430 status_t status;
0431
0432 if ((NULL == config) || (mode >= kLCDIFV2_PD_Max) || (layer >= kLCDIFV2_PD_LayerMax))
0433 {
0434 status = kStatus_InvalidArgument;
0435 }
0436 else
0437 {
0438 config->pdAlphaMode = kLCDIFV2_PD_AlphaStraight;
0439 config->pdColorMode = kLCDIFV2_PD_ColorWithAlpha;
0440 config->pdGlobalAlphaMode = kLCDIFV2_PD_LocalAlpha;
0441 config->pdFactorMode = s_lcdifv2PdLayerFactors[mode][(uint8_t)layer];
0442 config->alphaMode = kLCDIFV2_AlphaPoterDuff;
0443
0444 status = kStatus_Success;
0445 }
0446
0447 return status;
0448 }
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 status_t LCDIFV2_GetMultiLayerGlobalAlpha(const uint8_t blendedAlpha[], uint8_t globalAlpha[], uint8_t layerCount)
0478 {
0479 status_t status = kStatus_Success;
0480 int16_t curLayer = (int16_t)layerCount - 1;
0481 int left = 255;
0482 int tmpAlpha;
0483
0484 assert((layerCount > 1U) && (layerCount <= (uint8_t)LCDIFV2_LAYER_COUNT));
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503 globalAlpha[0] = 255U;
0504
0505 while (curLayer > 0)
0506 {
0507 tmpAlpha = (int)blendedAlpha[curLayer] * 255 / left;
0508 if (tmpAlpha > 255)
0509 {
0510 status = kStatus_InvalidArgument;
0511 break;
0512 }
0513
0514 globalAlpha[curLayer] = (uint8_t)tmpAlpha;
0515 left -= (int)blendedAlpha[curLayer];
0516
0517 if (left <= 0)
0518 {
0519 status = kStatus_InvalidArgument;
0520 break;
0521 }
0522
0523 curLayer--;
0524 }
0525
0526 return status;
0527 }