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

📄 enchw.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       This software is confidential and proprietary and may be used        --
--        only as expressly authorized by a licensing agreement from          --
--                                                                            --
--                            Hantro Products Oy.                             --
--                                                                            --
--      In the event of publication, the following notice is applicable:      --
--                                                                            --
--                   (C) COPYRIGHT 2005 HANTRO PRODUCTS OY                    --
--                            ALL RIGHTS RESERVED                             --
--                                                                            --
--          The entire notice above must be reproduced on all copies.         --
--                                                                            --
--------------------------------------------------------------------------------
--
--  Project  : 1200s
--
--  Abstract : Module for encoder HW registers access
--
-------------------------------------------------------------------------------*/

//------------------------------------------------------------------------------
//
//  Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------

/*------------------------------------------------------------------------------

    Table of context

    1. Include headers
    2. Module defines
    3. Local function prototypes
    4. Functions

------------------------------------------------------------------------------*/


/*------------------------------------------------------------------------------
    1. Include headers
------------------------------------------------------------------------------*/

#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <csp.h>

#include "enchw.h"

/*------------------------------------------------------------------------------
    2. Module defines
------------------------------------------------------------------------------*/

#define ENCHW_HWID_REG              0x88
#define ENCHW_HWID_MASK             0xFFFF0000
#define ENCHW_HWID_VAL              0x52510000

#define ENCHW_REGMAP_SIZE           35*4
#define ENCHW_REGMAP_PADDR          CSP_BASE_REG_PA_MPEG4_ENCODER

#define ENCHW_REG32(eh,o)           (*(volatile unsigned long*)((eh)->RegBase + (o)))
#define ENCHW_WRITE_REG32(eh,o,v)   do { ENCHW_REG32(eh,o) = (v); } while (0)
#define ENCHW_READ_REG32(eh,o )     ENCHW_REG32(eh,o)

#define ENCHW_MUTEX                 _T("ENCHW_MUTEX")

/*------------------------------------------------------------------------------
    3. Local function prototypes
------------------------------------------------------------------------------*/

static int  EnableEncoderHw(void);
static void DisableEncoderHw(void);

static __inline u32  EnableRegAccess ( EncHw_t* enchw, u32 offset );
static __inline void RestoreRegAccess( EncHw_t* enchw, u32 clearmask );


/*------------------------------------------------------------------------------
    4. Functions
------------------------------------------------------------------------------*/

/*------------------------------------------------------------------------------
    
    EncHw_Init

------------------------------------------------------------------------------*/
EncHw_t* EncHw_Init(void)
{
    EncHw_t* enchw;
    PHYSICAL_ADDRESS phyAddr;
    u32 hwId;
    int status;

    // 1. Allocate EncHw instance
    enchw = (EncHw_t*)malloc( sizeof(EncHw_t) );
    if( enchw==NULL )
    {
        return NULL;
    }
    
    // Reset enchw instance values
    enchw->RegBase = NULL;
    enchw->RegSize = 0;
    enchw->Mutex   = NULL;

    // 2. Enable power and clocks for encoder HW
    status = EnableEncoderHw();
    if( status )
    {
        EncHw_Release( enchw );
        return NULL;
    }

    // 3. Map HW registers to user sape
    phyAddr.QuadPart = ENCHW_REGMAP_PADDR;
    enchw->RegBase = MmMapIoSpace( phyAddr, ENCHW_REGMAP_SIZE, FALSE );
    if( enchw->RegBase == NULL ) 
    {
        EncHw_Release( enchw );
        return NULL;
    }

    enchw->RegSize = ENCHW_REGMAP_SIZE;

    // 4. Check for correct encoder by reading HW ID
    hwId = EncHw_ReadReg( enchw, ENCHW_HWID_REG );

    if( (hwId&ENCHW_HWID_MASK) != ENCHW_HWID_VAL )
    {
        EncHw_Release( enchw );
        return NULL;
    }

    // 5. Create mutex
    enchw->Mutex = CreateMutex( NULL, FALSE, ENCHW_MUTEX );
    if( enchw->Mutex==NULL )
    {
        EncHw_Release( enchw );
        return NULL;
    }

    return enchw;
}

/*------------------------------------------------------------------------------
    
    EncHw_Release

------------------------------------------------------------------------------*/
void EncHw_Release( EncHw_t* enchw )
{
    ASSERT( enchw!=NULL );

    // 5. Delete mutex
    if( enchw->Mutex != NULL )
    {
        CloseHandle( enchw->Mutex );
        enchw->Mutex = NULL;
    }

    // 4. Nothing to be done for HW ID check!

    // 3. Release HW registers mapping
    if( enchw->RegBase != NULL )
    {
        MmUnmapIoSpace( enchw->RegBase, enchw->RegSize );
        enchw->RegBase = NULL;
        enchw->RegSize = 0;
    }

    // 2. Disable power/clocks for encoder HW
    DisableEncoderHw();

    // 1. Free encoder HW instance
    free( enchw );
}

/*------------------------------------------------------------------------------
    
    EncHw_Reset

------------------------------------------------------------------------------*/
void EncHw_Reset( EncHw_t* enchw )
{
    u32 reg;
    ASSERT( enchw!=NULL );

    // Clear all regs but read-only HwId. HCLK enabled by WriteReg.
    for( reg=0 ; reg < ENCHW_REGMAP_SIZE-4 ; reg += 4 )
        EncHw_WriteReg( enchw, reg, 0 );
}

/*------------------------------------------------------------------------------

    EncHw_WriteReg

------------------------------------------------------------------------------*/
void EncHw_WriteReg( EncHw_t* enchw, u32 offset, u32 val )
{
    u32 saved;
    
    ASSERT( enchw!=NULL && offset<=enchw->RegSize );

    saved = EnableRegAccess( enchw, offset );
    ENCHW_WRITE_REG32( enchw, offset, val );
    RestoreRegAccess( enchw, saved );
}

/*------------------------------------------------------------------------------

    EncHw_ReadReg

------------------------------------------------------------------------------*/
u32 EncHw_ReadReg( EncHw_t* enchw, u32 offset )
{
    u32 val, saved;
    ASSERT( enchw!=NULL && offset<=enchw->RegSize );

    saved = EnableRegAccess( enchw, offset );
    val = ENCHW_READ_REG32( enchw, offset );
    RestoreRegAccess( enchw, saved );

    return val;
}

/*------------------------------------------------------------------------------

    IIM mapping

------------------------------------------------------------------------------*/
#define IIM_BASE              CSP_BASE_REG_PA_IIM
#define IIM_SIZE              0x1800
#define IIM_REG32(o)          (*(volatile unsigned long*)(iimBase + (o)))
#define IIM_WRITE_REG32(o,v)  do { IIM_REG32(o) = (v); } while (0)
#define IIM_READ_REG32(o )    IIM_REG32(o)

/*------------------------------------------------------------------------------

    EnableEncoderHw

------------------------------------------------------------------------------*/
i32 EnableEncoderHw( void )
{
    PHYSICAL_ADDRESS phyAddr;
    PUCHAR iimBase;

    DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IIM,
DDK_CLOCK_GATE_MODE_ENABLED_ALL);
 
    // Map IIM registers
    phyAddr.QuadPart = IIM_BASE;
    iimBase = MmMapIoSpace( phyAddr, IIM_SIZE, FALSE );
                                
    if( iimBase == NULL ) 
    {
        return -1;
    }
        
    // Override fuse for Hantro HW clock
    if( IIM_READ_REG32(0x808) & 0x04 && !(IIM_READ_REG32(0x800) & 1<<5)
)
    {
        IIM_WRITE_REG32( 0x808, IIM_READ_REG32(0x808) & 0xfffffffb );
    }
 
    // Unmap IIM
    MmUnmapIoSpace( iimBase, IIM_SIZE );
 
    DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IIM,
DDK_CLOCK_GATE_MODE_DISABLED);
 
    // Save current settings and enable encoder HW clock
    DDKClockSetGatingMode( DDK_CLOCK_GATE_INDEX_MPEG4, DDK_CLOCK_GATE_MODE_ENABLED_ALL );
 
    return 0;
}

/*------------------------------------------------------------------------------

    DisableEncoderHw

------------------------------------------------------------------------------*/
void DisableEncoderHw(void)
{
    DDKClockSetGatingMode( DDK_CLOCK_GATE_INDEX_MPEG4, DDK_CLOCK_GATE_MODE_DISABLED );
}

/*------------------------------------------------------------------------------

    EnagleRegAccess

------------------------------------------------------------------------------*/
static __inline u32 EnableRegAccess( EncHw_t* enchw, u32 offset )
{
    #define IPS  0
    #define HCLK 1
    static const u32 clockSource[] =
    {
        /*0x00*/ IPS,   /*0x04*/ IPS,   /*0x08*/ IPS,   /*0x0C*/ IPS,
        /*0x10*/ HCLK,  /*0x14*/ IPS,   /*0x18*/ IPS,   /*0x1C*/ IPS,
        /*0x20*/ IPS,   /*0x24*/ IPS,   /*0x28*/ IPS,   /*0x2C*/ HCLK,
        /*0x30*/ IPS,   /*0x34*/ IPS,   /*0x38*/ IPS,   /*0x3C*/ IPS,
        /*0x40*/ IPS,   /*0x44*/ IPS,   /*0x48*/ IPS,   /*0x4C*/ IPS,
        /*0x50*/ IPS,   /*0x54*/ IPS,   /*0x58*/ IPS,   /*0x5C*/ HCLK,
        /*0x60*/ HCLK,  /*0x64*/ HCLK,  /*0x68*/ HCLK,  /*0x6C*/ HCLK,
        /*0x70*/ IPS,   /*0x74*/ IPS,   /*0x78*/ IPS,   /*0x7C*/ IPS,
        /*0x80*/ HCLK,  /*0x84*/ IPS,   /*0x88*/ IPS
    };
    #undef IPS
    #undef HCLK

    static const u32 clockSourceSize = sizeof(clockSource)/sizeof(clockSource[0]);
    u32 clearmask = 0;

    offset /= 4;
    
    if( offset < clockSourceSize && clockSource[offset] /* == HCLK */ )
    {
       u32 val = ENCHW_READ_REG32( enchw, 0 );
       clearmask = ~val & (1<<12);
       ENCHW_WRITE_REG32( enchw, 0, val | 1<<12 );
    }

    return clearmask;
}

/*------------------------------------------------------------------------------

    RestoreRegAccess

------------------------------------------------------------------------------*/
static __inline void RestoreRegAccess( EncHw_t* enchw, u32 clearmask )
{
    if( clearmask ) ENCHW_REG32(enchw,0) &= ~clearmask;
}

⌨️ 快捷键说明

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