📄 philips_dtv_ref4.c
字号:
#ifdef __BIG_ENDIAN__
for (j = 3; j >= 0; j--)
#else
for (j = 0; j < 4; j++)
#endif
{
/* get flash into write state */
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[b + 0x555] = 0xa0000000;
flashBaseAddress[a + j] = d << 24;
while (((UInt8) ((flashBaseAddress[a + j] >> 24) & 0xff)) != (UInt8) d)
{
if (i++ > 100000)
{
return FLASH_ERR_WRITE;
}
}
d >>= 8;
}
/* switch back to super I/O bank, this is the default bank */
TRY(dtvRef4_bankSwitch(DTV_REF4_XIO_SIO_BANK));
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dtvRef4FlashReadBlock(UInt32 address, UInt32 * data, UInt32 numberOfWords)
{
tmLibdevErr_t err;
UInt32 d = 0;
UInt32 a = address << 2;
Int j, i;
tmAssert(data, FLASH_ERR_NULL_POINTER);
tmAssert(flashInitialized, FLASH_ERR_NOT_INITIALIZED);
err = dtvRef4_bankSwitch(DTV_REF4_XIO_FLASH_BANK);
if (err != TMLIBDEV_OK)
return err;
for (i = 0; i < numberOfWords; i++)
{
#ifdef __BIG_ENDIAN__
for (j = 3; j >= 1; j--)
#else
for (j = 0; j < 3; j++)
#endif
{
d |= flashBaseAddress[a + j] & 0xff000000;
d >>= 8;
}
d |= flashBaseAddress[a + j] & 0xff000000;
*data++ = d;
d = 0;
a += 4;
}
/* switch back to super I/O bank, this is the default bank */
TRY(dtvRef4_bankSwitch(DTV_REF4_XIO_SIO_BANK));
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dtvRef4FlashWriteBlock(UInt32 address, UInt32 * data, UInt32 numberOfWords)
{
tmLibdevErr_t err;
UInt32 d;
UInt32 b, a;
UInt32 i = 0;
Int j, k;
tmAssert(flashInitialized, FLASH_ERR_NOT_INITIALIZED);
err = dtvRef4_bankSwitch(DTV_REF4_XIO_FLASH_BANK);
if (err != TMLIBDEV_OK)
return err;
a = address << 2;
b = findFlashBank(a) * DTV_REF4_FLASH_BANK_SIZE;
d = *data;
for (k = 0; k < numberOfWords; k++)
{
#ifdef __BIG_ENDIAN__
for (j = 3; j >= 0; j--)
#else
for (j = 0; j < 4; j++)
#endif
{
/* get flash into write state */
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[b + 0x555] = 0xa0000000;
flashBaseAddress[a + j] = d << 24;
while (((UInt8) ((flashBaseAddress[a + j] >> 24) & 0xff)) != (UInt8) d)
{
if (i++ > 100000)
{
return FLASH_ERR_WRITE;
}
}
d >>= 8;
}
a += 4;
d = data[k+1];
i = 0;
b = findFlashBank(a) * DTV_REF4_FLASH_BANK_SIZE;
}
/* switch back to super I/O bank, this is the default bank */
TRY(dtvRef4_bankSwitch(DTV_REF4_XIO_SIO_BANK));
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dtvRef4FlashEraseSector(UInt32 sector)
{
tmLibdevErr_t err = 0;
UInt32 i = 0;
UInt32 s, b;
tmAssert(flashInitialized, FLASH_ERR_NOT_INITIALIZED);
err = dtvRef4_bankSwitch(DTV_REF4_XIO_FLASH_BANK);
if (err != TMLIBDEV_OK)
return err;
if (sector >= DTV_REF4_FLASH_SECTOR_NR)
return FLASH_ERR_INVALID_SECTOR_NR;
s = (sector * DTV_REF4_FLASH_SECTOR_SIZE) << 2;
b = findFlashBank(s) * DTV_REF4_FLASH_BANK_SIZE;
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[b + 0x555] = 0x80000000;
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[s] = 0x30000000;
/* wait 50 microseconds (sector erase timeout) */
microsleep(50);
/* wait max. 8s until sector is erased (typ. time should be 1s per sector) */
while ((flashBaseAddress[s] >> 24)!= 0xff)
{
if (i++ > 8000000)
return FLASH_ERR_ERASE_TIMEOUT;
microsleep(1);
}
/* switch back to super I/O bank, this is the default bank */
TRY(dtvRef4_bankSwitch(DTV_REF4_XIO_SIO_BANK));
return TMLIBDEV_OK;
}
static tmLibdevErr_t eraseBank(UInt32 bank)
{
tmLibdevErr_t err = 0;
UInt32 i = 0;
UInt32 b;
tmAssert(flashInitialized, FLASH_ERR_NOT_INITIALIZED);
err = dtvRef4_bankSwitch(DTV_REF4_XIO_FLASH_BANK);
if (err != TMLIBDEV_OK)
return err;
b = bank * DTV_REF4_FLASH_BANK_SIZE;
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[b + 0x555] = 0x80000000;
flashBaseAddress[b + 0x555] = 0xaa000000;
flashBaseAddress[b + 0x2aa] = 0x55000000;
flashBaseAddress[b + 0x555] = 0x10000000;
/* wait max. 100s until chip is erased (typ. time should be 64s per chip) */
while ((flashBaseAddress[b] >> 24)!= 0xff)
{
if (i++ > 100000)
return FLASH_ERR_ERASE_TIMEOUT;
microsleep(1000);
}
/* switch back to super I/O bank, this is the default bank */
TRY(dtvRef4_bankSwitch(DTV_REF4_XIO_SIO_BANK));
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dtvRef4FlashEraseAll(void)
{
tmLibdevErr_t err = 0;
UInt32 i;
tmAssert(flashInitialized, FLASH_ERR_NOT_INITIALIZED);
for (i = 0; i < 4; i++)
{
err = eraseBank(i);
if (err != TMLIBDEV_OK)
return err;
}
return TMLIBDEV_OK;
}
/***********************************************************************/
static tmLibdevErr_t dtvRef4_board_activate(pcomponent_t comp)
{
DP(("dtvRef4_board_activate\n"));
TRY(dtvRef4_board_detect());
DP((" after detect\n"));
TRY(dtvRef4_board_init());
DP((" after init\n"));
/* the board has to be registered now */
TRY(dtvRef4_board_register(comp));
DP((" after register\n"));
return TMLIBDEV_OK;
}
static tmLibdevErr_t dtvRef4_board_init(void)
{
pprocCapabilities_t procCap;
Int i;
xioRegParam_t xioRegParams;
volatile unsigned int *gpioBase;
UInt8 xioRegDefaultValues[0xB]
= { 0x1f, /* 0: w: audio DAC enable */
0x03, /* 1: w: L3 and NIM stuff */
0x80, /* 2: w: video and modem */
0x0d, /* 3: w: L3CK, sync sel, modem sel */
0x00, /* 4: r: interrupt status (read) */
0x00, /* 5: w: software resets */
0x07, /* 6: w: VGA and video */
0x00, /* 7: -: Does not exist? */
0x00, /* 8: r: NIM Status (read) */
0xff, /* 9: r: ID and data */
0x00, /* A: w: peripheral int masks */
};
em9010Param_t em9010Params;
w83977atfParams_t sioParams;
iicDirectionParam_t iicDirectionParams;
p1394Param_t p1394Params;
DP_R4(("dtvRef4_board_init\n"));
TRY(procGetCapabilities(&procCap));
if (boardID == BOARD_VERSION_PHILIPS_DTV_REF4_V3)
{
/* Make J00 - J04 and J11 - J13 outputs and write default values to the
output pins. Make also pins J05 to J10 (interrupt inputs) outputs
and set them to 0. This is necessary because otherwise there is a
weak drive to high. Before the software can use those interrupts it must
set the GPIO pins to be inputs. */
MMIO(GPIOJ_OUT) = 0x00001800;
MMIO(GPIOJ_MODE) = 0x0aaaaaaa;
iicDirectionParams.directionSwitchFunction = dtvRef4DirectionSwitch;
iicDirectionParams.defaultDirection = IIC_DIRECTION_BOOT_ROM;
TRY(iicDirectionInit(&iicDirectionParams));
}
/* disable PCI access to protect XIO against speculative loads */
pciSetDC_LOCK(PCI_DC_LOCK_CTL_PDS);
/* initialize XIO */
MMIO(XIO_CTL) = DTV_REF4_XIO_BASE | 0x0000079f ;
xioRegParams.bank = DTV_REF4_XIO_REG_BANK;
xioRegParams.bankSwitchFunc = dtvRef4_bankSwitch;
xioRegParams.baseAddress = (UInt32 *) DTV_REF4_XIO_REG_BASE;
xioRegParams.numWriteRegs = 0xA;
xioRegParams.defaultValues = xioRegDefaultValues;
TRY(xioRegInit(&xioRegParams));
/* make sure VO clock is running at 27MHz! */
MMIO(GPIOD_MODE) = 0x3;
MMIO(VO_CLOCK) = (UInt) (0.5 + (1431655765.0 * 27000000 / procCap->cpuClockFrequency));
MMIO(VO_CTL) = 0x02700000;
microsleep(10000); /* wait for 10ms */
/* disable all GPIO interrupts */
gpioBase = &(MMIO(GPIO_EV1));
for (i=0; i<16; i+=2)
gpioBase[i] = 0xFF000000;
/* reset peripherals */
TRY(xioRegWriteBit(2, 0x01, False)); /* reset low */
TRY(xioRegWriteBit(2, 0x01, True)); /* reset high */
/* initialize EM9010 (nova) */
em9010Params.regWrite = 6;
em9010Params.regRead = 9;
em9010Params.clk = 0x04;
em9010Params.sdaW = 0x01;
em9010Params.sdaWEn = 0x02;
em9010Params.sdaR = 0x04;
/* initialize xio pins */
TRY(em9010Init(&em9010Params));
/* Enable HDVO output */
TRY(em9010WriteReg(&em9010Params, 0x0a, 0x77));
TRY(em9010WriteReg(&em9010Params, 0x08, 0x10));
TRY(em9010WriteReg(&em9010Params, 0x05, 0x70));
/* initialize super I/O */
sioParams.sioWriteFunc = ref4SioWrite;
sioParams.sioReadFunc = ref4SioRead;
if (boardID == BOARD_VERSION_PHILIPS_DTV_REF4_V3)
{
DP((" no shared interrupts\n"));
sioParams.sharedInterrupts = False;
}
else
sioParams.sharedInterrupts = True;
TRY(w83977atfInit(&sioParams));
/* initialize 1394 read/write */
p1394Params.p1394Write = ref4P1394Write;
p1394Params.p1394Read = ref4P1394Read;
TRY(p1394BoardInit(&p1394Params));
/* disable VO clock, SAA7125 should be in a good state now */
MMIO(GPIOD_MODE) = 0;
MMIO(VO_CLOCK) = 0;
/* disable GPIO pins */
return TMLIBDEV_OK;
} /* end of dtvRef4_board_init() */
/******************** dtvRef4_board_detect *******************************
* Returns true if the hardware appears to be a Philips DTV Ref. 4 board.
*/
static tmLibdevErr_t dtvRef4_board_detect(void)
{
Int line, error;
UInt d1, d2, mfgID;
UInt8 eepromData[8];
DP_R4(("dtvRef4_board_detect\n"));
for (line = 0; line < 8; line++) {
error = iicReadReg(IIC_EEPROM_ADDRESS, line, &d1);
if (error)
{
TRY(iicReadReg(IIC_EEPROM_ADDRESS, line, &d1));
}
error = iicReadReg(IIC_EEPROM_ADDRESS, line, &d2);
if (error)
{
TRY(iicReadReg(IIC_EEPROM_ADDRESS, line, &d2));
}
eepromData[line] = d1;
}
mfgID = (eepromData[3] << 8) + eepromData[4];
boardID = (eepromData[1] << 8) + eepromData[2];
if (mfgID != BOARD_ID_PHILIPS_MFG_ID)
{
DP((" unknown mfgID %#x\n", mfgID));
return BOARD_ERR_UNKNOWN_BOARD;
}
if ((boardID == BOARD_VERSION_PHILIPS_DTV_REF4) ||
(boardID == BOARD_VERSION_PHILIPS_DTV_REF4_V3))
return TMLIBDEV_OK;
DP((" unknown boardID %#x\n", boardID));
return BOARD_ERR_UNKNOWN_BOARD;
}
static tmLibdevErr_t dtvRef4_board_register(pcomponent_t comp)
{
TRY(tsaBoardRegisterFlash(0, &dtvRef4Flash));
TRY(tsaBoardRegisterAO(0, &dtvRef4_ao_1));
TRY(tsaBoardRegisterAO(1, &dtvRef4_ao_2));
TRY(tsaBoardRegisterSPDO(0, &dtvRef4_spdo));
TRY(tsaBoardRegisterVO(0, &dtvRef4_vo));
TRY(tsaBoardRegisterSSI(0, &dtvRef4_afe));
TRY(tsaBoardRegisterHDVO(0, &dtvRef4_hdvo));
TRY(tsaBoardRegisterMP(0, &dtvRef4_mp));
TRY(tsaBoardRegisterPIC(0, &dtvRef4PIC));
TRY(tsaBoardRegisterIR(0, &dtvRef4IR));
TRY(tsaBoardRegisterUart(0, &dtvRef4Uart1));
TRY(tsaBoardRegisterUart(1, &dtvRef4Uart2));
TRY(tsaBoardRegisterP1394(0, &dtvRef4P1394));
/* register the DTV REF 4 (Jupiter) */
if (boardID == BOARD_VERSION_PHILIPS_DTV_REF4)
TRY(tsaBoardRegisterBoard(boardID, "DTV REF 4"));
else
TRY(tsaBoardRegisterBoard(boardID, "DTV REF 4 V3"));
TRY(gpioInit()); /* register GPIO */
return TMLIBDEV_OK;
}
TSA_COMP_DEF_O_COMPONENT( Philips_dtvRef4,
TSA_COMP_BUILD_ARG_LIST_2("bsp/boardID", "bsp/uart"),
dtvRef4_board_activate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -