/* * This function set up the main chip clock. * * Input: Frequency to be set. */ static void setChipClock(unsigned int frequency) { pll_value_t pll; unsigned int ulActualMxClk; /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ if (getChipType() == SM750LE) return; if (frequency) { /* * Set up PLL, a structure to hold the value to be set in clocks. */ pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ pll.clockType = MXCLK_PLL; /* * Call calcPllValue() to fill up the other fields for PLL structure. * Sometime, the chip cannot set up the exact clock required by User. * Return value from calcPllValue() gives the actual possible clock. */ ulActualMxClk = calcPllValue(frequency, &pll); /* Master Clock Control: MXCLK_PLL */ POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); } }
/* only timing related registers will be programed */ static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll) { int ret = 0; int cnt = 0; unsigned int ulTmpValue, ulReg; if (pll->clockType == SECONDARY_PLL) { /* programe secondary pixel clock */ POKE32(CRT_PLL_CTRL, formatPllReg(pll)); POKE32(CRT_HORIZONTAL_TOTAL, FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); POKE32(CRT_HORIZONTAL_SYNC, FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); POKE32(CRT_VERTICAL_TOTAL, FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); POKE32(CRT_VERTICAL_SYNC, FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); ulTmpValue = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)| FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)| FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)| FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE); if (getChipType() == SM750LE) { displayControlAdjust_SM750LE(pModeParam, ulTmpValue); } else { ulReg = PEEK32(CRT_DISPLAY_CTRL) & FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE) & FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE) & FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING) & FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE); POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg); } } else if (pll->clockType == PRIMARY_PLL) { unsigned int ulReservedBits; POKE32(PANEL_PLL_CTRL, formatPllReg(pll)); POKE32(PANEL_HORIZONTAL_TOTAL, FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); POKE32(PANEL_HORIZONTAL_SYNC, FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); POKE32(PANEL_VERTICAL_TOTAL, FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); POKE32(PANEL_VERTICAL_SYNC, FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); ulTmpValue = FIELD_VALUE(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)| FIELD_VALUE(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)| FIELD_VALUE(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, pModeParam->clock_phase_polarity)| FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)| FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE); ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC, ACTIVE_LOW); ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); /* May a hardware bug or just my test chip (not confirmed). * PANEL_DISPLAY_CTRL register seems requiring few writes * before a value can be successfully written in. * Added some masks to mask out the reserved bits. * Note: This problem happens by design. The hardware will wait for the * next vertical sync to turn on/off the plane. */ POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg); while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) { cnt++; if (cnt > 1000) break; POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg); } } else { ret = -1; } return ret; }