⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 davincihd_pll.c

📁 用于dm6467 开发平台的uboot源码
💻 C
字号:
/*
 *  Copyright 2007 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

/*
 *  PLL Setup
 *
 */

#include "davincihd_pll.h"
#include "davincihd_ddr.h"

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _enablePll0( clock_mode, multiplier, post_div )                         *
 *      Setup PLL0                                                          *
 *                                                                          *
 *      Inputs:                                                             *
 *          clock_mode -> [0:OSCIN / 1:CLKIN]                               *
 *          multiplier -> [0-63] -> 27MHz * multiplier + 1                  *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_enablePll0( Uint16 clock_mode, Uint16 multiplier, Uint16 post_div )
{
#ifdef ARM_SIDE

    volatile Uint32* pll_ctl    = ( volatile Uint32* )&PLL0_PLLCTL;
    volatile Uint32* pll_pllm   = ( volatile Uint32* )&PLL0_PLLM;
    volatile Uint32* pll_cmd    = ( volatile Uint32* )&PLL0_PLLCMD;
  //volatile Uint32* pll_postdiv= ( volatile Uint32* )&PLL0_POSTDIV;
  //volatile Uint32* pll_bpdiv  = ( volatile Uint32* )&PLL0_BPDIV;
    volatile Uint32* pll_div1   = ( volatile Uint32* )&PLL0_PLLDIV1;
    volatile Uint32* pll_div2   = ( volatile Uint32* )&PLL0_PLLDIV2;
    volatile Uint32* pll_div3   = ( volatile Uint32* )&PLL0_PLLDIV3;
    volatile Uint32* pll_div4   = ( volatile Uint32* )&PLL0_PLLDIV4;
  //volatile Uint32* pll_div5   = ( volatile Uint32* )&PLL0_PLLDIV5;
  //volatile Uint32* pll_div6   = ( volatile Uint32* )&PLL0_PLLDIV6;
  //volatile Uint32* pll_div7   = ( volatile Uint32* )&PLL0_PLLDIV7;
  //volatile Uint32* pll_div8   = ( volatile Uint32* )&PLL0_PLLDIV8;
    volatile Uint32* pll_div9   = ( volatile Uint32* )&PLL0_PLLDIV9;
  //Uint32 postdiv = 0;
  //Uint32 bypass_div = 1;

    /*
     *  Step 0 - Ignore request if the PLL is already set as is
     *//*
    if ( ( ( *pll_ctl & 0x0100 ) >> 8 ) == clock_mode )
        if ( ( *pll_pllm & 0x3f ) == ( multiplier & 0x3f ) )
            if ( ( *pll_postdiv & 0x1f ) == ( postdiv & 0x1f ) )
                return 0;   // Already Set*/

    /*
     *  Step 0 - Stop all peripheral operations ( except DDR )
     */

    /*
     *  Step 1 - Set clock mode
     */
    if ( clock_mode == OSCIN )
        *pll_ctl &= ~0x0100;    // Onchip Oscillator

    if ( clock_mode == CLKIN )
        *pll_ctl |= 0x0100;     // External Clock

    /*
     *  Step 2 - Set PLL to bypass
     *         - Wait for PLL to stabilize
     */
    *pll_ctl &= ~0x0020;
    *pll_ctl &= ~0x0001;
    _wait( 150 );

    /*
     *  Step 3 - Reset PLL
     */
    *pll_ctl |= 0x0008;

    /*
     *  Step 4 - Disable PLL
     *  Step 5 - Powerup PLL
     *  Step 6 - Enable PLL
     *  Step 7 - Wait for PLL to stabilize
     */
    *pll_ctl |= 0x0010;         // Disable PLL
    *pll_ctl &= ~0x0002;        // Power up PLL
    *pll_ctl &= ~0x0010;        // Enable PLL
    _wait( 150 );               // Wait for PLL to stabilize

    /*
     *  Step 8 - Load PLL multiplier
     */
    *pll_pllm = multiplier & 0x3f;

    /*
     *  Step 9 - Set PLL post dividers
     *           Div1: (Fixed @ /1)DSP
     *           Div2: (Fixed @ /2)ARM/PCI/GraphicsEngine/HD-VICP0-1/EDMA/SCR
     *           Div3: (Fixed @ /4)Peripherals
     *           Div4: ATA
     *           Div5: SYSCLK5
     *           Div6: SYSCLK6
     *           Div7: SYSCLK7
     *           Div8: SYSCLK8
     *           Div9: VLYNQ
     */
    *pll_div1   = 0x8000 | DIV_1;       // DSP
    *pll_div2   = 0x8000 | DIV_2;       // ARM/PCI/HDVICP
    *pll_div3   = 0x8000 | DIV_4;       // Peripherals
    *pll_div4   = 0x8000 | DIV_6;       // ATA divider
/*  *pll_div5   = 0x8000 | DIV_8;
    *pll_div6   = 0x8000 | DIV_8;
    *pll_div7   = 0x8000 | DIV_8;
    *pll_div8   = 0x8000 | DIV_8;*/
    *pll_div9   = 0x8000 | DIV_6;       // VLYNQ divider
/*  *pll_bpdiv  = 0x0000 | bypass_div;  // Bypass divider
    *pll_postdiv= 0x8000 | postdiv;     // Post divider*/
    *pll_cmd |= 0x0001;                 // GO
    _wait( 2000 );

    /*
     *  Step 10 - Wait for PLL to reset ( 2000 cycles )
     *  Step 11 - Release from reset
     */
    *pll_ctl &= ~0x0008;
    _wait( 2000 );

    /*
     *  Step 12 - Wait for PLL to re-lock ( 2000 cycles )
     *  Step 13 - Switch out of BYPASS mode
     */
    *pll_ctl |= 0x0001;
    _wait( 2000 );

#endif

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _setPll0_divider( pll_divider, divide_by )                              *
 *      Set the individual dividers on PLL0                                 *
 *                                                                          *
 *      Inputs:                                                             *
 *          pll_divider -> Divider # [4-9]                                  *
 *          divide_by   -> Divide by # [0-31]                               *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_setPll0_divider( Uint16 pll_divider, Uint16 divide_by )
{

#ifdef ARM_SIDE

    switch( pll_divider )
    {
        /* ATA Divider */
        case 4:
            PLL0_PLLDIV4 = 0x8000 | ( divide_by & 0x1f );
            break;

        /* SYS CLK 5 */
        case 5:
            PLL0_PLLDIV5 = 0x8000 | ( divide_by & 0x1f );
            break;

        /* SYS CLK 6 */
        case 6:
            PLL0_PLLDIV6 = 0x8000 | ( divide_by & 0x1f );
            break;

        /* SYS CLK 7 */
        case 7:
            PLL0_PLLDIV7 = 0x8000 | ( divide_by & 0x1f );
            break;

        /* SYS CLK 8 */
        case 8:
            PLL0_PLLDIV8 = 0x8000 | ( divide_by & 0x1f );
            break;

        /* VLYNQ Divider */
        case 9:
            PLL0_PLLDIV9 = 0x8000 | ( divide_by & 0x1f );
            break;

        default:
            return -1;
    }

    _wait( 2000 );

#endif

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _enablePll1( clock_mode, multiplier, ddr2_div )                         *
 *      Setup PLL1                                                          *
 *                                                                          *
 *      Inputs:                                                             *
 *          clock_mode -> [0:OSCIN / 1:CLKIN]                               *
 *          multiplier -> [0-63] -> 27MHz * multiplier + 1                  *
 *          ddr2_div   -> [0-31] -> 27MHz * multiplier + 1 / 2 * ddr2_div   *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_enablePll1( Uint16 clock_mode, Uint16 multiplier, Uint16 ddr2_div )
{
#ifdef ARM_SIDE
    Uint32 davincihd_enablepll1_fn;

    volatile Uint32* pll_ctl    = ( volatile Uint32* )&PLL1_PLLCTL;
    volatile Uint32* pll_pllm   = ( volatile Uint32* )&PLL1_PLLM;
    volatile Uint32* pll_cmd    = ( volatile Uint32* )&PLL1_PLLCMD;
    volatile Uint32* pll_stat   = ( volatile Uint32* )&PLL1_PLLSTAT;
    volatile Uint32* pll_div1   = ( volatile Uint32* )&PLL1_PLLDIV1;


    davincihd_enablepll1_fn = ( Uint32 )&DAVINCIHD_enablePll1;
    if ( ( davincihd_enablepll1_fn >= ( DDR_BASE ) )
      && ( davincihd_enablepll1_fn <= ( DDR_BASE + DDR_SIZE ) ) )
        return -1;

    /*
     *  Step 0 - Ignore request if the PLL is already set as is
     */
    if ( ( ( *pll_ctl & 0x0100 ) >> 8 ) == clock_mode )
        if ( ( *pll_pllm & 0x3f ) == ( multiplier & 0x3f ) )
            if ( ( *pll_div1 & 0x1f ) == ( ddr2_div & 0x1f ) )
            return 0;

    /*
     *  Step 1 - Set clock mode
     */
    if ( clock_mode == OSCIN )
        *pll_ctl &= ~0x0100;    // Onchip Oscillator

    if ( clock_mode == CLKIN )
        *pll_ctl |= 0x0100;     // External Clock

    /*
     *  Step 2 - Set PLL to bypass
     *         - Wait for PLL to stabilize
     */
    *pll_ctl &= ~0x0020;
    *pll_ctl &= ~0x0001;
    _wait( 150 );

    /*
     *  Step 3 - Reset PLL
     */
    *pll_ctl |= 0x0008;

    /*
     *  Step 4 - Disable PLL
     *  Step 5 - Powerup PLL
     *  Step 6 - Enable PLL
     *  Step 7 - Wait for PLL to stabilize
     */
    *pll_ctl |= 0x0010;         // Disable PLL
    *pll_ctl &= ~0x0002;        // Power up PLL
    *pll_ctl &= ~0x0010;        // Enable PLL
    _wait( 150 );               // Wait for PLL to stabilize

    /*
     *  Step 8 - Load PLL multiplier
     */
    *pll_pllm = multiplier & 0x3f;

    /*
     *  Step 9 - Load PLL dividers ( 1:DDR2 )
     */
    *pll_div1 = 0x8000 | ( ddr2_div & 0x1f );
    *pll_cmd |= 0x0001;             // GO
    while( ( *pll_stat & 1 ) != 0 );// Wait for phase alignment
    _wait( 2000 );

    /*
     *  Step 10 - Wait for PLL to reset ( 2000 cycles )
     *  Step 11 - Release from reset
     */
    *pll_ctl &= ~0x0008;
    _wait( 2000 );

    /*
     *  Step 12 - Wait for PLL to re-lock ( 2000 cycles )
     *  Step 13 - Switch out of BYPASS mode
     */
    *pll_ctl |= 0x0001;
    _wait( 2000 );

#endif

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -