File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008 #include "fsl_mipi_dsi.h"
0009
0010
0011
0012
0013
0014
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.mipi_dsi_split"
0017 #endif
0018
0019
0020 #ifndef FSL_MIPI_DSI_IDLE_TIMEOUT
0021 #define FSL_MIPI_DSI_IDLE_TIMEOUT 0x1000U
0022 #endif
0023
0024
0025 #define DSI_DPHY_PLL_CN_MIN 1U
0026 #define DSI_DPHY_PLL_CN_MAX 32U
0027
0028
0029 #define DSI_DPHY_PLL_REFCLK_CN_MIN 24000000U
0030 #define DSI_DPHY_PLL_REFCLK_CN_MAX 30000000U
0031
0032
0033 #define DSI_DPHY_PLL_CM_MIN 16U
0034 #define DSI_DPHY_PLL_CM_MAX 255U
0035
0036
0037 #define DSI_DPHY_PLL_VCO_MAX 1500000000U
0038 #define DSI_DPHY_PLL_VCO_MIN (DSI_DPHY_PLL_REFCLK_CN_MIN * DSI_DPHY_PLL_CM_MIN)
0039
0040 #define PKT_CONTROL_WORD_COUNT(wc) ((uint32_t)(wc) << 0U)
0041 #define PKT_CONTROL_VC(vc) ((uint32_t)(vc) << 16U)
0042 #define PKT_CONTROL_HEADER_TYPE(ht) ((uint32_t)(ht) << 18U)
0043 #define PKT_CONTROL_HS_MASK (1UL << 24U)
0044 #define PKT_CONTROL_BTA_MASK (1UL << 25U)
0045 #define PKT_CONTROL_BTA_ONLY_MASK (1UL << 26U)
0046
0047
0048 #define DSI_THS_ZERO_BYTE_CLK_BASE 6U
0049 #define DSI_TCLK_ZERO_BYTE_CLK_BASE 3U
0050 #define DSI_THS_PREPARE_HALF_ESC_CLK_BASE 2U
0051 #define DSI_TCLK_PREPARE_HALF_ESC_CLK_BASE 2U
0052
0053 #define DSI_THS_PREPARE_HALF_ESC_CLK_MIN (DSI_THS_PREPARE_HALF_ESC_CLK_BASE)
0054 #define DSI_TCLK_PREPARE_HALF_ESC_CLK_MIN (DSI_TCLK_PREPARE_HALF_ESC_CLK_BASE)
0055
0056 #define DSI_THS_PREPARE_HALF_ESC_CLK_MAX (5U)
0057 #define DSI_TCLK_PREPARE_HALF_ESC_CLK_MAX (3U)
0058
0059
0060 #define DSI_NS_TO_BYTE_CLK(ns, byte_clk_khz) ((ns) * (byte_clk_khz) / 1000000U)
0061
0062 #define DSI_NS_UI_TO_BYTE_CLK(ns, UI, byte_clk_khz) ((((ns) * (byte_clk_khz)) + ((UI)*125000U)) / 1000000U)
0063
0064
0065 #define DSI_HSA_OVERHEAD_BYTE 10UL
0066 #define DSI_HFP_OVERHEAD_BYTE 12UL
0067 #define DSI_HBP_OVERHEAD_BYTE 10UL
0068
0069 #define DSI_INT_STATUS_TRIGGER_MASK \
0070 ((uint32_t)kDSI_InterruptGroup1ResetTriggerReceived | (uint32_t)kDSI_InterruptGroup1TearTriggerReceived | \
0071 (uint32_t)kDSI_InterruptGroup1AckTriggerReceived)
0072 #define DSI_INT_STATUS_ERROR_REPORT_MASK (0xFFFFU << 9U)
0073
0074 #if (defined(FSL_FEATURE_DSI_CSR_OFFSET) && (0 != FSL_FEATURE_DSI_CSR_OFFSET))
0075 #if (defined(FSL_FEATURE_LDB_COMBO_PHY) && (0 != FSL_FEATURE_LDB_COMBO_PHY))
0076 typedef MIPI_DSI_LVDS_COMBO_CSR_Type MIPI_DSI_CSR_Type;
0077 #define MIPI_DSI_CSR_ULPS_CTRL(csr) ((csr)->ULPS_CTRL)
0078 #define MIPI_DSI_CSR_ULPS_CTRL_ULPS_MASK MIPI_DSI_LVDS_COMBO_CSR_ULPS_CTRL_TX_ULPS_MASK
0079 #define MIPI_DSI_CSR_PXL2DPI(csr) ((csr)->PXL2DPI_CTRL)
0080 #else
0081 #define MIPI_DSI_CSR_ULPS_CTRL(csr) ((csr)->TX_ULPS_ENABLE)
0082 #define MIPI_DSI_CSR_ULPS_CTRL_ULPS_MASK MIPI_DSI_TX_ULPS_ENABLE_TX_ULPS_ENABLE_MASK
0083 #define MIPI_DSI_CSR_PXL2DPI(csr) ((csr)->PXL2DPI_CONFIG)
0084 #endif
0085
0086 #define DSI_GET_CSR(dsi_base) ((MIPI_DSI_CSR_Type *)(((uint32_t)(dsi_base)) - (uint32_t)FSL_FEATURE_DSI_CSR_OFFSET))
0087 #endif
0088
0089
0090 typedef void (*dsi_isr_t)(const MIPI_DSI_Type *base, dsi_handle_t *handle);
0091
0092
0093
0094
0095 #if defined(DSI_HOST_DSI_IRQS)
0096
0097 static const IRQn_Type s_dsiIRQ[] = DSI_HOST_DSI_IRQS;
0098 #endif
0099
0100 static DSI_HOST_Type *const s_dsiBases[] = DSI_HOST_BASE_PTRS;
0101
0102 static dsi_handle_t *s_dsiHandle[ARRAY_SIZE(s_dsiBases)];
0103
0104 static dsi_isr_t s_dsiIsr;
0105
0106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0107
0108 static const clock_ip_name_t s_dsiClocks[] = MIPI_DSI_HOST_CLOCKS;
0109 #endif
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static uint32_t DSI_GetInstance(const MIPI_DSI_Type *base);
0121
0122 #if !((defined(FSL_FEATURE_MIPI_NO_DPHY_PLL)) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_DPHY_PLL))
0123
0124
0125
0126
0127
0128
0129 static uint8_t DSI_EncodeDphyPllCn(uint8_t cn);
0130
0131
0132
0133
0134
0135
0136
0137 static uint8_t DSI_EncodeDphyPllCm(uint8_t cm);
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static uint32_t DSI_DphyGetPllDivider(
0158 uint32_t *cn, uint32_t *cm, uint32_t *co, uint32_t refClkFreq_Hz, uint32_t desiredOutFreq_Hz);
0159 #endif
0160
0161
0162
0163
0164
0165
0166 static void DSI_ApbClearRxFifo(const MIPI_DSI_Type *base);
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 static status_t DSI_HandleResult(const MIPI_DSI_Type *base,
0182 uint32_t intFlags1,
0183 uint32_t intFlags2,
0184 dsi_transfer_t *xfer);
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static status_t DSI_PrepareApbTransfer(const MIPI_DSI_Type *base, dsi_transfer_t *xfer);
0199
0200
0201
0202
0203
0204
0205
0206
0207 static uint32_t DSI_NsToByteClk(uint32_t ns, uint32_t byteclk_khz)
0208 {
0209 return (ns * byteclk_khz) / 1000000UL;
0210 }
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 static uint32_t DSI_NsUiToByteClk(uint32_t ns, uint32_t UI, uint32_t byteclk_khz)
0223 {
0224 return ((ns * byteclk_khz) + (UI * 125000UL)) / 1000000UL;
0225 }
0226
0227
0228
0229
0230
0231 static uint32_t DSI_GetInstance(const MIPI_DSI_Type *base)
0232 {
0233 uint32_t instance;
0234
0235
0236 for (instance = 0; instance < ARRAY_SIZE(s_dsiBases); instance++)
0237 {
0238 if (s_dsiBases[instance] == base->host)
0239 {
0240 break;
0241 }
0242 }
0243
0244 assert(instance < ARRAY_SIZE(s_dsiBases));
0245
0246 return instance;
0247 }
0248
0249 #if !((defined(FSL_FEATURE_MIPI_NO_DPHY_PLL)) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_DPHY_PLL))
0250 static uint8_t DSI_EncodeDphyPllCn(uint8_t cn)
0251 {
0252 uint8_t ret = 0U;
0253
0254 assert((cn >= 1U) && (cn <= 32U));
0255
0256 if (1U == cn)
0257 {
0258 ret = 0x1FU;
0259 }
0260 else
0261 {
0262 ret = (uint8_t)((0x65BD44E0UL >> ((uint32_t)cn - 2U)) & 0x1FU);
0263 }
0264
0265 return ret;
0266 }
0267
0268 static uint8_t DSI_EncodeDphyPllCm(uint8_t cm)
0269 {
0270 uint8_t ret = 0U;
0271
0272 assert(cm >= 16U);
0273
0274 if (cm <= 31U)
0275 {
0276 ret = 0xE0U | cm;
0277 }
0278 else if (cm <= 63U)
0279 {
0280 ret = 0xC0U | (cm & 0x1FU);
0281 }
0282 else if (cm <= 127U)
0283 {
0284 ret = 0x80U | (cm & 0x3FU);
0285 }
0286 else
0287 {
0288 ret = cm & 0xCFU;
0289 }
0290
0291 return ret;
0292 }
0293
0294 static uint32_t DSI_DphyGetPllDivider(
0295 uint32_t *cn, uint32_t *cm, uint32_t *co, uint32_t refClkFreq_Hz, uint32_t desiredOutFreq_Hz)
0296 {
0297 uint32_t cnCur;
0298 uint32_t cmCur;
0299 uint32_t coShiftCur;
0300 uint32_t pllFreqCur;
0301 uint32_t diffCur;
0302 uint32_t vcoFreq;
0303 uint32_t refClk_CN;
0304 uint32_t diff = 0xFFFFFFFFU;
0305 uint32_t pllFreqCandidate = 0U;
0306
0307
0308 for (coShiftCur = 0U; coShiftCur <= 3U; coShiftCur++)
0309 {
0310
0311 vcoFreq = desiredOutFreq_Hz << coShiftCur;
0312
0313
0314 if (vcoFreq < DSI_DPHY_PLL_VCO_MIN)
0315 {
0316 continue;
0317 }
0318
0319
0320 if (vcoFreq > DSI_DPHY_PLL_VCO_MAX)
0321 {
0322 break;
0323 }
0324
0325
0326 for (cnCur = DSI_DPHY_PLL_CN_MIN; cnCur <= DSI_DPHY_PLL_CN_MAX; cnCur++)
0327 {
0328
0329 refClk_CN = refClkFreq_Hz / cnCur;
0330
0331
0332 if (refClk_CN > DSI_DPHY_PLL_REFCLK_CN_MAX)
0333 {
0334 continue;
0335 }
0336
0337
0338 if (refClk_CN < DSI_DPHY_PLL_REFCLK_CN_MIN)
0339 {
0340 break;
0341 }
0342
0343
0344 cmCur = (vcoFreq + (refClk_CN / 2U)) / refClk_CN;
0345
0346
0347 if ((DSI_DPHY_PLL_CM_MAX + 1U) == cmCur)
0348 {
0349 cmCur = DSI_DPHY_PLL_CM_MAX;
0350 }
0351
0352 if ((cmCur < DSI_DPHY_PLL_CM_MIN) || (cmCur > DSI_DPHY_PLL_CM_MAX))
0353 {
0354 continue;
0355 }
0356
0357
0358 pllFreqCur = (refClk_CN * cmCur) >> coShiftCur;
0359
0360 if (pllFreqCur > desiredOutFreq_Hz)
0361 {
0362 diffCur = (pllFreqCur - desiredOutFreq_Hz);
0363 }
0364 else
0365 {
0366 diffCur = (desiredOutFreq_Hz - pllFreqCur);
0367 }
0368
0369
0370 if (diffCur < diff)
0371 {
0372 diff = diffCur;
0373 *cm = cmCur;
0374 *cn = cnCur;
0375 *co = coShiftCur;
0376 pllFreqCandidate = pllFreqCur;
0377
0378
0379 if (0U == diff)
0380 {
0381 break;
0382 }
0383 }
0384 }
0385
0386
0387 if (0U == diff)
0388 {
0389 break;
0390 }
0391 }
0392
0393 return pllFreqCandidate;
0394 }
0395 #endif
0396
0397 static void DSI_ApbClearRxFifo(const MIPI_DSI_Type *base)
0398 {
0399 volatile uint32_t dummy = 0U;
0400 uint32_t level = base->apb->PKT_FIFO_RD_LEVEL;
0401
0402 while (0U != (level--))
0403 {
0404 dummy = base->apb->PKT_RX_PAYLOAD;
0405 }
0406
0407 (void)dummy;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 void DSI_Init(const MIPI_DSI_Type *base, const dsi_config_t *config)
0420 {
0421 assert(NULL != config);
0422
0423 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0424 (void)CLOCK_EnableClock(s_dsiClocks[DSI_GetInstance(base)]);
0425 #endif
0426
0427 DSI_HOST_Type *host = base->host;
0428
0429 #if (defined(FSL_FEATURE_DSI_CSR_OFFSET) && (0 != FSL_FEATURE_DSI_CSR_OFFSET))
0430 MIPI_DSI_CSR_Type *csr = DSI_GET_CSR(base);
0431 if (config->enableTxUlps)
0432 {
0433 MIPI_DSI_CSR_ULPS_CTRL(csr) = MIPI_DSI_CSR_ULPS_CTRL_ULPS_MASK;
0434 }
0435 else
0436 {
0437 MIPI_DSI_CSR_ULPS_CTRL(csr) = 0U;
0438 }
0439 #endif
0440
0441 host->CFG_NUM_LANES = config->numLanes - 1UL;
0442
0443 if (config->enableNonContinuousHsClk)
0444 {
0445 host->CFG_NONCONTINUOUS_CLK = 0x01U;
0446 }
0447 else
0448 {
0449 host->CFG_NONCONTINUOUS_CLK = 0x00U;
0450 }
0451
0452 if (config->autoInsertEoTp)
0453 {
0454 host->CFG_AUTOINSERT_EOTP = 0x01U;
0455 }
0456 else
0457 {
0458 host->CFG_AUTOINSERT_EOTP = 0x00U;
0459 }
0460
0461 host->CFG_EXTRA_CMDS_AFTER_EOTP = config->numExtraEoTp;
0462 host->CFG_HTX_TO_COUNT = config->htxTo_ByteClk;
0463 host->CFG_LRX_H_TO_COUNT = config->lrxHostTo_ByteClk;
0464 host->CFG_BTA_H_TO_COUNT = config->btaTo_ByteClk;
0465
0466 DSI_ApbClearRxFifo(base);
0467
0468
0469
0470
0471 base->apb->IRQ_MASK = 0xFFFFFFFFU;
0472 base->apb->IRQ_MASK2 = 0xFFFFFFFFU;
0473 }
0474
0475
0476
0477
0478
0479
0480
0481
0482 void DSI_Deinit(const MIPI_DSI_Type *base)
0483 {
0484 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0485 (void)CLOCK_DisableClock(s_dsiClocks[DSI_GetInstance(base)]);
0486 #endif
0487 }
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506 void DSI_GetDefaultConfig(dsi_config_t *config)
0507 {
0508 assert(NULL != config);
0509
0510
0511 (void)memset(config, 0, sizeof(*config));
0512
0513 config->numLanes = 4;
0514 config->enableNonContinuousHsClk = false;
0515 config->enableTxUlps = false;
0516 config->autoInsertEoTp = true;
0517 config->numExtraEoTp = 0;
0518 config->htxTo_ByteClk = 0;
0519 config->lrxHostTo_ByteClk = 0;
0520 config->btaTo_ByteClk = 0;
0521 }
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 void DSI_SetDpiConfig(const MIPI_DSI_Type *base,
0537 const dsi_dpi_config_t *config,
0538 uint8_t numLanes,
0539 uint32_t dpiPixelClkFreq_Hz,
0540 uint32_t dsiHsBitClkFreq_Hz)
0541 {
0542 assert(NULL != config);
0543
0544
0545 uint32_t coff = (numLanes * dsiHsBitClkFreq_Hz) / (dpiPixelClkFreq_Hz * 8U);
0546
0547 DSI_HOST_DPI_INTFC_Type *dpi = base->dpi;
0548
0549 #if (defined(FSL_FEATURE_DSI_CSR_OFFSET) && (0 != FSL_FEATURE_DSI_CSR_OFFSET))
0550 MIPI_DSI_CSR_Type *csr = DSI_GET_CSR(base);
0551 MIPI_DSI_CSR_PXL2DPI(csr) = (uint32_t)config->dpiColorCoding;
0552 #endif
0553
0554 dpi->PIXEL_PAYLOAD_SIZE = config->pixelPayloadSize;
0555 dpi->INTERFACE_COLOR_CODING = (uint32_t)config->dpiColorCoding;
0556 dpi->PIXEL_FORMAT = (uint32_t)config->pixelPacket;
0557 dpi->VIDEO_MODE = (uint32_t)config->videoMode;
0558
0559 if (kDSI_DpiBllpLowPower == config->bllpMode)
0560 {
0561 dpi->BLLP_MODE = 0x1U;
0562 dpi->USE_NULL_PKT_BLLP = 0x0U;
0563 }
0564 else if (kDSI_DpiBllpBlanking == config->bllpMode)
0565 {
0566 dpi->BLLP_MODE = 0x0U;
0567 dpi->USE_NULL_PKT_BLLP = 0x0U;
0568 }
0569 else
0570 {
0571 dpi->BLLP_MODE = 0x0U;
0572 dpi->USE_NULL_PKT_BLLP = 0x1U;
0573 }
0574
0575 if (0U != (config->polarityFlags & (uint32_t)kDSI_DpiVsyncActiveHigh))
0576 {
0577 dpi->VSYNC_POLARITY = 0x01U;
0578 }
0579 else
0580 {
0581 dpi->VSYNC_POLARITY = 0x00U;
0582 }
0583
0584 if (0U != (config->polarityFlags & (uint32_t)kDSI_DpiHsyncActiveHigh))
0585 {
0586 dpi->HSYNC_POLARITY = 0x01U;
0587 }
0588 else
0589 {
0590 dpi->HSYNC_POLARITY = 0x00U;
0591 }
0592
0593 dpi->HFP = config->hfp * coff - DSI_HFP_OVERHEAD_BYTE;
0594 dpi->HBP = config->hbp * coff - DSI_HBP_OVERHEAD_BYTE;
0595 dpi->HSA = config->hsw * coff - DSI_HSA_OVERHEAD_BYTE;
0596 dpi->PIXEL_FIFO_SEND_LEVEL = config->pixelPayloadSize;
0597
0598 dpi->VBP = config->vbp;
0599 dpi->VFP = config->vfp;
0600
0601 dpi->VACTIVE = config->panelHeight - 1UL;
0602
0603
0604 }
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619 uint32_t DSI_InitDphy(const MIPI_DSI_Type *base, const dsi_dphy_config_t *config, uint32_t refClkFreq_Hz)
0620 {
0621 assert(NULL != config);
0622
0623 DSI_HOST_NXP_FDSOI28_DPHY_INTFC_Type *dphy = base->dphy;
0624 DSI_HOST_Type *host = base->host;
0625
0626 #if !((defined(FSL_FEATURE_MIPI_NO_DPHY_PLL)) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_DPHY_PLL))
0627 uint32_t cn;
0628 uint32_t cm;
0629 uint32_t co;
0630 uint32_t outputPllFreq;
0631
0632 outputPllFreq = DSI_DphyGetPllDivider(&cn, &cm, &co, refClkFreq_Hz, config->txHsBitClk_Hz);
0633
0634
0635 if (0U == outputPllFreq)
0636 {
0637 return 0U;
0638 }
0639
0640
0641 dphy->CN = (uint32_t)DSI_EncodeDphyPllCn((uint8_t)cn);
0642 dphy->CM = (uint32_t)DSI_EncodeDphyPllCm((uint8_t)cm);
0643 dphy->CO = co;
0644 #endif
0645
0646
0647 dphy->M_PRG_HS_PREPARE = (uint32_t)config->tHsPrepare_HalfEscClk - DSI_THS_PREPARE_HALF_ESC_CLK_BASE;
0648 dphy->MC_PRG_HS_PREPARE = (uint32_t)config->tClkPrepare_HalfEscClk - DSI_TCLK_PREPARE_HALF_ESC_CLK_BASE;
0649 dphy->M_PRG_HS_ZERO = (uint32_t)config->tHsZero_ByteClk - DSI_THS_ZERO_BYTE_CLK_BASE;
0650 dphy->MC_PRG_HS_ZERO = (uint32_t)config->tClkZero_ByteClk - DSI_TCLK_ZERO_BYTE_CLK_BASE;
0651 dphy->M_PRG_HS_TRAIL = config->tHsTrail_ByteClk;
0652 dphy->MC_PRG_HS_TRAIL = config->tClkTrail_ByteClk;
0653
0654 host->CFG_T_PRE = config->tClkPre_ByteClk;
0655 host->CFG_T_POST = config->tClkPost_ByteClk;
0656 host->CFG_TX_GAP = config->tHsExit_ByteClk;
0657 host->CFG_TWAKEUP = config->tWakeup_EscClk;
0658
0659 #if defined(MIPI_RTERM_SEL_dphy_rterm_sel_MASK)
0660 dphy->RTERM_SEL = MIPI_RTERM_SEL_dphy_rterm_sel_MASK;
0661 #endif
0662 #if defined(MIPI_TX_RCAL_dphy_tx_rcal_MASK)
0663 dphy->TX_RCAL = 1;
0664 #endif
0665 dphy->RXLPRP = 1;
0666 dphy->RXCDRP = 1;
0667
0668
0669 dphy->AUTO_PD_EN = 0x1U;
0670
0671 dphy->TST = 0x25U;
0672
0673 #if !((defined(FSL_FEATURE_MIPI_NO_PLL) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_PLL)))
0674
0675 dphy->PD_PLL = 0U;
0676
0677
0678 while (0UL == dphy->LOCK)
0679 {
0680 }
0681 #endif
0682
0683
0684 dphy->PD_TX = 0U;
0685
0686 #if !((defined(FSL_FEATURE_MIPI_NO_PLL) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_PLL)))
0687 return outputPllFreq;
0688 #else
0689 return config->txHsBitClk_Hz;
0690 #endif
0691 }
0692
0693
0694
0695
0696
0697
0698
0699
0700 void DSI_DeinitDphy(const MIPI_DSI_Type *base)
0701 {
0702 #if !((defined(FSL_FEATURE_MIPI_NO_DPHY_PLL)) && (0 != FSL_FEATURE_MIPI_DSI_HOST_NO_DPHY_PLL))
0703
0704 base->dphy->PD_PLL = 1U;
0705 #endif
0706
0707
0708 base->dphy->PD_TX = 1U;
0709 }
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722 void DSI_GetDphyDefaultConfig(dsi_dphy_config_t *config, uint32_t txHsBitClk_Hz, uint32_t txEscClk_Hz)
0723 {
0724 assert(NULL != config);
0725
0726
0727 (void)memset(config, 0, sizeof(*config));
0728
0729 uint32_t byteClkFreq_kHz = txHsBitClk_Hz / 8U / 1000U;
0730 uint32_t txEscClk_kHz = txEscClk_Hz / 1000U;
0731
0732 config->txHsBitClk_Hz = txHsBitClk_Hz;
0733
0734
0735 config->tHsExit_ByteClk = (uint8_t)(DSI_NsToByteClk(100U, byteClkFreq_kHz) + 1U);
0736
0737
0738 config->tWakeup_EscClk = (txEscClk_Hz / 1000U) + 1U;
0739
0740
0741 config->tHsPrepare_HalfEscClk =
0742 (uint8_t)(((40U * txEscClk_kHz * 2U) / 1000000U) + (4U * txEscClk_Hz * 2U / txHsBitClk_Hz) + 1U);
0743 if (config->tHsPrepare_HalfEscClk < DSI_THS_PREPARE_HALF_ESC_CLK_MIN)
0744 {
0745 config->tHsPrepare_HalfEscClk = DSI_THS_PREPARE_HALF_ESC_CLK_MIN;
0746 }
0747 else if (config->tHsPrepare_HalfEscClk > DSI_THS_PREPARE_HALF_ESC_CLK_MAX)
0748 {
0749 config->tHsPrepare_HalfEscClk = DSI_THS_PREPARE_HALF_ESC_CLK_MAX;
0750 }
0751 else
0752 {
0753
0754 }
0755
0756
0757 config->tClkPrepare_HalfEscClk = (uint8_t)((38U * txEscClk_kHz * 2U) / 1000000U + 1U);
0758 if (config->tClkPrepare_HalfEscClk < DSI_TCLK_PREPARE_HALF_ESC_CLK_MIN)
0759 {
0760 config->tClkPrepare_HalfEscClk = DSI_TCLK_PREPARE_HALF_ESC_CLK_MIN;
0761 }
0762 else if (config->tClkPrepare_HalfEscClk > DSI_TCLK_PREPARE_HALF_ESC_CLK_MAX)
0763 {
0764 config->tClkPrepare_HalfEscClk = DSI_TCLK_PREPARE_HALF_ESC_CLK_MAX;
0765 }
0766 else
0767 {
0768
0769 }
0770
0771
0772 config->tHsZero_ByteClk = (uint8_t)(DSI_NsUiToByteClk(105U, 6U, byteClkFreq_kHz) + 1U);
0773 if (config->tHsZero_ByteClk < DSI_THS_ZERO_BYTE_CLK_BASE)
0774 {
0775 config->tHsZero_ByteClk = DSI_THS_ZERO_BYTE_CLK_BASE;
0776 }
0777
0778
0779 config->tClkZero_ByteClk = (uint8_t)(DSI_NsToByteClk(262U, byteClkFreq_kHz) + 1U);
0780 if (config->tClkZero_ByteClk < DSI_TCLK_ZERO_BYTE_CLK_BASE)
0781 {
0782 config->tClkZero_ByteClk = DSI_TCLK_ZERO_BYTE_CLK_BASE;
0783 }
0784
0785
0786
0787 config->tHsTrail_ByteClk = (uint8_t)(DSI_NsUiToByteClk(60U, 8U, byteClkFreq_kHz) + 1U);
0788
0789
0790
0791 config->tClkTrail_ByteClk = (uint8_t)(DSI_NsUiToByteClk(60U, 4U, byteClkFreq_kHz) + 1U);
0792
0793
0794
0795
0796
0797
0798
0799
0800 config->tClkPre_ByteClk = (uint8_t)(DSI_NsUiToByteClk(88U, 8U, byteClkFreq_kHz) + 1U) + config->tClkZero_ByteClk;
0801
0802
0803
0804
0805
0806
0807 config->tClkPost_ByteClk = (uint8_t)(DSI_NsUiToByteClk(60U, 52U, byteClkFreq_kHz) + 1U) + config->tClkTrail_ByteClk;
0808 }
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825 void DSI_SetApbPacketControl(
0826 const MIPI_DSI_Type *base, uint16_t wordCount, uint8_t virtualChannel, dsi_tx_data_type_t dataType, uint8_t flags)
0827 {
0828 uint32_t pktCtrl = PKT_CONTROL_WORD_COUNT(wordCount) | PKT_CONTROL_HEADER_TYPE(dataType);
0829
0830 #if defined(DSI_HOST_PKT_CONTROL_VC)
0831 pktCtrl |= (uint32_t)DSI_HOST_PKT_CONTROL_VC(virtualChannel);
0832 #endif
0833
0834 if (0U != (flags & (uint8_t)kDSI_TransferUseHighSpeed))
0835 {
0836 pktCtrl |= PKT_CONTROL_HS_MASK;
0837 }
0838
0839 if (0U != (flags & (uint8_t)kDSI_TransferPerformBTA))
0840 {
0841 pktCtrl |= PKT_CONTROL_BTA_MASK;
0842 }
0843
0844 base->apb->PKT_CONTROL = pktCtrl;
0845 }
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856 void DSI_WriteApbTxPayload(const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize)
0857 {
0858 DSI_WriteApbTxPayloadExt(base, payload, payloadSize, false, 0U);
0859 }
0860
0861 void DSI_WriteApbTxPayloadExt(
0862 const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize, bool sendDscCmd, uint8_t dscCmd)
0863 {
0864 uint32_t firstWord;
0865 uint16_t i;
0866 uint16_t payloadSizeLocal = payloadSize;
0867 const uint8_t *payloadLocal = payload;
0868
0869 DSI_HOST_APB_PKT_IF_Type *apb = base->apb;
0870
0871 if (sendDscCmd)
0872 {
0873 payloadSizeLocal += 1U;
0874 }
0875
0876 assert(payloadSizeLocal <= FSL_DSI_TX_MAX_PAYLOAD_BYTE);
0877
0878
0879 if (sendDscCmd)
0880 {
0881 firstWord = dscCmd;
0882 }
0883 else
0884 {
0885 firstWord = *payloadLocal;
0886 payloadLocal++;
0887 }
0888
0889 payloadSizeLocal--;
0890
0891 for (i = 1U; i < 4U; i++)
0892 {
0893 if (payloadSizeLocal > 0U)
0894 {
0895 firstWord |= ((uint32_t)(*payloadLocal) << (i << 3U));
0896 payloadLocal++;
0897 payloadSizeLocal--;
0898 }
0899 else
0900 {
0901 break;
0902 }
0903 }
0904
0905 apb->TX_PAYLOAD = firstWord;
0906
0907
0908 for (i = 0; i < (payloadSizeLocal / 4U); i++)
0909 {
0910 apb->TX_PAYLOAD = ((uint32_t)payloadLocal[3] << 24U) | ((uint32_t)payloadLocal[2] << 16U) |
0911 ((uint32_t)payloadLocal[1] << 8U) | payloadLocal[0];
0912 payloadLocal = &payloadLocal[4];
0913 }
0914
0915
0916 switch (payloadSizeLocal & 0x03U)
0917 {
0918 case 3:
0919 apb->TX_PAYLOAD = ((uint32_t)payloadLocal[2] << 16U) | ((uint32_t)payloadLocal[1] << 8U) | payloadLocal[0];
0920 break;
0921 case 2:
0922 apb->TX_PAYLOAD = ((uint32_t)payloadLocal[1] << 8U) | payloadLocal[0];
0923 break;
0924 case 1:
0925 apb->TX_PAYLOAD = payloadLocal[0];
0926 break;
0927 default:
0928
0929 break;
0930 }
0931 }
0932
0933 static status_t DSI_PrepareApbTransfer(const MIPI_DSI_Type *base, dsi_transfer_t *xfer)
0934 {
0935
0936 assert(xfer->rxDataSize <= FSL_DSI_RX_MAX_PAYLOAD_BYTE);
0937 assert(xfer->txDataSize <= FSL_DSI_TX_MAX_PAYLOAD_BYTE);
0938
0939 uint8_t txDataIndex;
0940 uint16_t wordCount;
0941 uint32_t intFlags1;
0942 uint32_t intFlags2;
0943 uint32_t txDataSize;
0944
0945 status_t status;
0946
0947 if (xfer->rxDataSize > FSL_DSI_RX_MAX_PAYLOAD_BYTE)
0948 {
0949 status = kStatus_DSI_NotSupported;
0950 }
0951 else
0952 {
0953 if (xfer->rxDataSize != 0U)
0954 {
0955 xfer->flags |= (uint8_t)kDSI_TransferPerformBTA;
0956 }
0957
0958
0959
0960
0961
0962 if (xfer->sendDscCmd)
0963 {
0964 txDataSize = (uint32_t)xfer->txDataSize + 1U;
0965 }
0966 else
0967 {
0968 txDataSize = (uint32_t)xfer->txDataSize;
0969 }
0970
0971
0972 if (txDataSize <= 2U)
0973 {
0974 if (0U == txDataSize)
0975 {
0976 wordCount = 0U;
0977 }
0978 else
0979 {
0980 txDataIndex = 0;
0981
0982 if (xfer->sendDscCmd)
0983 {
0984 wordCount = xfer->dscCmd;
0985 }
0986 else
0987 {
0988 wordCount = xfer->txData[txDataIndex++];
0989 }
0990
0991 if (2U == txDataSize)
0992 {
0993 wordCount |= ((uint16_t)xfer->txData[txDataIndex] << 8U);
0994 }
0995 }
0996 }
0997
0998 else
0999 {
1000 wordCount = (uint16_t)txDataSize;
1001 DSI_WriteApbTxPayloadExt(base, xfer->txData, xfer->txDataSize, xfer->sendDscCmd, xfer->dscCmd);
1002 }
1003
1004 DSI_SetApbPacketControl(base, wordCount, xfer->virtualChannel, xfer->txDataType, xfer->flags);
1005
1006
1007 DSI_GetAndClearInterruptStatus(base, &intFlags1, &intFlags2);
1008
1009 status = kStatus_Success;
1010 }
1011
1012 return status;
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 void DSI_ReadApbRxPayload(const MIPI_DSI_Type *base, uint8_t *payload, uint16_t payloadSize)
1027 {
1028 uint32_t tmp;
1029 uint16_t i;
1030 uint8_t *payloadLocal = payload;
1031
1032 for (i = 0; i < payloadSize / 4U; i++)
1033 {
1034 tmp = base->apb->PKT_RX_PAYLOAD;
1035 payloadLocal[0] = (uint8_t)(tmp & 0xFFU);
1036 payloadLocal[1] = (uint8_t)((tmp >> 8U) & 0xFFU);
1037 payloadLocal[2] = (uint8_t)((tmp >> 16U) & 0xFFU);
1038 payloadLocal[3] = (uint8_t)((tmp >> 24U) & 0xFFU);
1039 payloadLocal = &payloadLocal[4];
1040 }
1041
1042
1043 if (0U != (payloadSize & 0x03U))
1044 {
1045 tmp = base->apb->PKT_RX_PAYLOAD;
1046
1047 for (i = 0; i < (payloadSize & 0x3U); i++)
1048 {
1049 payloadLocal[i] = (uint8_t)(tmp & 0xFFU);
1050 tmp >>= 8U;
1051 }
1052 }
1053 }
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 status_t DSI_TransferBlocking(const MIPI_DSI_Type *base, dsi_transfer_t *xfer)
1073 {
1074 status_t status;
1075 uint32_t intFlags1Old;
1076 uint32_t intFlags2Old;
1077 uint32_t intFlags1New;
1078 uint32_t intFlags2New;
1079
1080 DSI_HOST_APB_PKT_IF_Type *apb = base->apb;
1081
1082
1083 while (0U != (apb->PKT_STATUS & (uint32_t)kDSI_ApbNotIdle))
1084 {
1085 }
1086
1087 status = DSI_PrepareApbTransfer(base, xfer);
1088
1089 if (kStatus_Success == status)
1090 {
1091 DSI_SendApbPacket(base);
1092
1093
1094 while (true)
1095 {
1096 DSI_GetAndClearInterruptStatus(base, &intFlags1Old, &intFlags2Old);
1097
1098 if (0U != (intFlags1Old & (uint32_t)kDSI_InterruptGroup1ApbNotIdle))
1099 {
1100 break;
1101 }
1102 }
1103
1104
1105 while (true)
1106 {
1107
1108 if (0U == (apb->PKT_STATUS & (uint32_t)kDSI_ApbNotIdle))
1109 {
1110 break;
1111 }
1112
1113
1114 if (0U != (base->host->RX_ERROR_STATUS &
1115 ((uint32_t)kDSI_RxErrorHtxTo | (uint32_t)kDSI_RxErrorLrxTo | (uint32_t)kDSI_RxErrorBtaTo)))
1116 {
1117 status = kStatus_Timeout;
1118 break;
1119 }
1120 }
1121
1122 DSI_GetAndClearInterruptStatus(base, &intFlags1New, &intFlags2New);
1123
1124 if (kStatus_Success == status)
1125 {
1126 status = DSI_HandleResult(base, intFlags1Old | intFlags1New, intFlags2Old | intFlags2New, xfer);
1127 }
1128 }
1129
1130 return status;
1131 }
1132
1133 static status_t DSI_HandleResult(const MIPI_DSI_Type *base,
1134 uint32_t intFlags1,
1135 uint32_t intFlags2,
1136 dsi_transfer_t *xfer)
1137 {
1138 uint32_t rxPktHeader;
1139 uint16_t actualRxByteCount;
1140 dsi_rx_data_type_t rxDataType;
1141 bool readRxDataFromPayload;
1142
1143
1144 if (0U != (((uint32_t)kDSI_InterruptGroup1HtxTo | (uint32_t)kDSI_InterruptGroup1LrxTo |
1145 (uint32_t)kDSI_InterruptGroup1BtaTo) &
1146 intFlags1))
1147 {
1148 return kStatus_Timeout;
1149 }
1150
1151
1152 if (0U != (((uint32_t)kDSI_InterruptGroup2EccMultiBit | (uint32_t)kDSI_InterruptGroup2CrcError) & intFlags2))
1153 {
1154 return kStatus_DSI_RxDataError;
1155 }
1156
1157
1158 if (0U != (xfer->flags & (uint32_t)kDSI_TransferPerformBTA))
1159 {
1160 if (0U != (intFlags1 & DSI_INT_STATUS_ERROR_REPORT_MASK))
1161 {
1162 return kStatus_DSI_ErrorReportReceived;
1163 }
1164
1165 if (0U != ((uint32_t)kDSI_InterruptGroup1ApbRxHeaderReceived & intFlags1))
1166 {
1167 rxPktHeader = DSI_GetRxPacketHeader(base);
1168 rxDataType = DSI_GetRxPacketType(rxPktHeader);
1169
1170
1171 if (kDSI_RxDataAckAndErrorReport == rxDataType)
1172 {
1173 return kStatus_DSI_ErrorReportReceived;
1174 }
1175 else
1176 {
1177 if ((kDSI_RxDataGenShortRdResponseOneByte == rxDataType) ||
1178 (kDSI_RxDataDcsShortRdResponseOneByte == rxDataType))
1179 {
1180 readRxDataFromPayload = false;
1181 actualRxByteCount = 1U;
1182 }
1183 else if ((kDSI_RxDataGenShortRdResponseTwoByte == rxDataType) ||
1184 (kDSI_RxDataDcsShortRdResponseTwoByte == rxDataType))
1185 {
1186 readRxDataFromPayload = false;
1187 actualRxByteCount = 2U;
1188 }
1189 else if ((kDSI_RxDataGenLongRdResponse == rxDataType) || (kDSI_RxDataDcsLongRdResponse == rxDataType))
1190 {
1191 readRxDataFromPayload = true;
1192 actualRxByteCount = DSI_GetRxPacketWordCount(rxPktHeader);
1193 }
1194 else
1195 {
1196 readRxDataFromPayload = false;
1197 xfer->rxDataSize = 0U;
1198 actualRxByteCount = 0U;
1199 }
1200
1201 xfer->rxDataSize = MIN(xfer->rxDataSize, actualRxByteCount);
1202
1203 if (xfer->rxDataSize > 0U)
1204 {
1205 if (readRxDataFromPayload)
1206 {
1207 DSI_ReadApbRxPayload(base, xfer->rxData, xfer->rxDataSize);
1208 }
1209 else
1210 {
1211 xfer->rxData[0] = (uint8_t)(rxPktHeader & 0xFFU);
1212
1213 if (2U == xfer->rxDataSize)
1214 {
1215 xfer->rxData[1] = (uint8_t)((rxPktHeader >> 8U) & 0xFFU);
1216 }
1217 }
1218 }
1219
1220 return kStatus_Success;
1221 }
1222 }
1223
1224 return kStatus_Success;
1225 }
1226 else
1227 {
1228
1229 if (0U != ((uint32_t)kDSI_InterruptGroup1ApbTxDone & intFlags1))
1230 {
1231 return kStatus_Success;
1232 }
1233 }
1234
1235 return kStatus_Fail;
1236 }
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248 status_t DSI_TransferCreateHandle(const MIPI_DSI_Type *base,
1249 dsi_handle_t *handle,
1250 dsi_callback_t callback,
1251 void *userData)
1252 {
1253 assert(NULL != handle);
1254
1255 uint32_t instance = DSI_GetInstance(base);
1256
1257
1258 (void)memset(handle, 0, sizeof(*handle));
1259
1260
1261 s_dsiHandle[instance] = handle;
1262 handle->callback = callback;
1263 handle->userData = userData;
1264 handle->isBusy = false;
1265 handle->dsi = base;
1266 s_dsiIsr = DSI_TransferHandleIRQ;
1267
1268 #if defined(DSI_HOST_DSI_IRQS)
1269
1270 (void)EnableIRQ(s_dsiIRQ[instance]);
1271 #endif
1272
1273 return kStatus_Success;
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290 status_t DSI_TransferNonBlocking(const MIPI_DSI_Type *base, dsi_handle_t *handle, dsi_transfer_t *xfer)
1291 {
1292 status_t status;
1293
1294 if (handle->isBusy)
1295 {
1296 status = kStatus_DSI_Busy;
1297 }
1298 else if (0U != (base->apb->PKT_STATUS & (uint32_t)kDSI_ApbNotIdle))
1299 {
1300 status = kStatus_DSI_Busy;
1301 }
1302 else
1303 {
1304 handle->xfer = *xfer;
1305
1306 status = DSI_PrepareApbTransfer(base, &handle->xfer);
1307
1308 if (kStatus_Success == status)
1309 {
1310 DSI_SendApbPacket(base);
1311 handle->isBusy = true;
1312
1313
1314 if (0U != (handle->xfer.flags & (uint32_t)kDSI_TransferPerformBTA))
1315 {
1316 DSI_EnableInterrupts(
1317 base,
1318 DSI_INT_STATUS_TRIGGER_MASK | (uint32_t)kDSI_InterruptGroup1ApbRxHeaderReceived |
1319 (uint32_t)kDSI_InterruptGroup1ApbRxPacketReceived | (uint32_t)kDSI_InterruptGroup1BtaTo |
1320 (uint32_t)kDSI_InterruptGroup1LrxTo | (uint32_t)kDSI_InterruptGroup1HtxTo |
1321 (uint32_t)kDSI_InterruptGroup1AckTriggerReceived,
1322 (uint32_t)kDSI_InterruptGroup2EccMultiBit | (uint32_t)kDSI_InterruptGroup2CrcError);
1323 }
1324 else
1325 {
1326 DSI_EnableInterrupts(base,
1327 (uint32_t)kDSI_InterruptGroup1ApbTxDone | (uint32_t)kDSI_InterruptGroup1HtxTo, 0U);
1328 }
1329 }
1330 }
1331
1332 return status;
1333 }
1334
1335
1336
1337
1338
1339
1340
1341 void DSI_TransferAbort(const MIPI_DSI_Type *base, dsi_handle_t *handle)
1342 {
1343 assert(NULL != handle);
1344
1345 if (handle->isBusy)
1346 {
1347
1348 DSI_DisableInterrupts(base,
1349 (uint32_t)kDSI_InterruptGroup1ApbTxDone | DSI_INT_STATUS_TRIGGER_MASK |
1350 DSI_INT_STATUS_ERROR_REPORT_MASK | (uint32_t)kDSI_InterruptGroup1ApbRxHeaderReceived |
1351 (uint32_t)kDSI_InterruptGroup1ApbRxPacketReceived |
1352 (uint32_t)kDSI_InterruptGroup1BtaTo | (uint32_t)kDSI_InterruptGroup1LrxTo |
1353 (uint32_t)kDSI_InterruptGroup1HtxTo,
1354 (uint32_t)kDSI_InterruptGroup2EccMultiBit | (uint32_t)kDSI_InterruptGroup2CrcError);
1355
1356
1357 (void)memset(&handle->xfer, 0, sizeof(handle->xfer));
1358
1359
1360 handle->isBusy = false;
1361 }
1362 }
1363
1364
1365
1366
1367
1368
1369
1370 void DSI_TransferHandleIRQ(const MIPI_DSI_Type *base, dsi_handle_t *handle)
1371 {
1372 assert(NULL != handle);
1373
1374 status_t status;
1375 uint32_t intFlags1;
1376 uint32_t intFlags2;
1377 uint32_t timeout;
1378 const MIPI_DSI_Type *dsi = handle->dsi;
1379
1380
1381 if (handle->isBusy)
1382 {
1383
1384 timeout = FSL_MIPI_DSI_IDLE_TIMEOUT;
1385 while (0U != (timeout--))
1386 {
1387 if (0U == (dsi->apb->PKT_STATUS & (uint32_t)kDSI_ApbNotIdle))
1388 {
1389 break;
1390 }
1391 }
1392
1393 if (0U == timeout)
1394 {
1395 DSI_TransferAbort(dsi, handle);
1396 status = kStatus_Timeout;
1397 }
1398 else
1399 {
1400
1401 DSI_DisableInterrupts(
1402 dsi,
1403 (uint32_t)kDSI_InterruptGroup1ApbTxDone | DSI_INT_STATUS_TRIGGER_MASK |
1404 DSI_INT_STATUS_ERROR_REPORT_MASK | (uint32_t)kDSI_InterruptGroup1ApbRxHeaderReceived |
1405 (uint32_t)kDSI_InterruptGroup1ApbRxPacketReceived | (uint32_t)kDSI_InterruptGroup1BtaTo |
1406 (uint32_t)kDSI_InterruptGroup1LrxTo | (uint32_t)kDSI_InterruptGroup1HtxTo,
1407 (uint32_t)kDSI_InterruptGroup2EccMultiBit | (uint32_t)kDSI_InterruptGroup2CrcError);
1408
1409 DSI_GetAndClearInterruptStatus(dsi, &intFlags1, &intFlags2);
1410
1411 status = DSI_HandleResult(dsi, intFlags1, intFlags2, &handle->xfer);
1412 handle->isBusy = false;
1413 }
1414
1415 if (NULL != handle->callback)
1416 {
1417 handle->callback(dsi, handle, status, handle->userData);
1418 }
1419 }
1420
1421 return;
1422 }
1423
1424 #if defined(DSI_HOST)
1425 void MIPI_DSI_DriverIRQHandler(void);
1426 void MIPI_DSI_DriverIRQHandler(void)
1427 {
1428
1429
1430
1431 s_dsiIsr(NULL, s_dsiHandle[0]);
1432 }
1433 #endif