hpi.c

来自「U-boot源码 ARM7启动代码」· C语言 代码 · 共 612 行 · 第 1/2 页

C
612
字号
/* * (C) Copyright 2006 * Markus Klotzbuecher, DENX Software Engineering, mk@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//* * Host Port Interface (HPI) *//* debug levels: *  0 : errors *  1 : usefull info *  2 : lots of info *  3 : noisy */#define DEBUG 0#include <config.h>#include <common.h>#include <mpc8xx.h>#include "pld.h"#include "hpi.h"#define	_NOT_USED_	0xFFFFFFFF/* original table: * - inserted loops to achieve long CS low and high Periods (~217ns) * - move cs high 2/4 to the right */const uint dsp_table_slow[] ={	/* single read   (offset  0x00 in upm ram) */	0x8fffdc04, 0x0fffdc84, 0x0fffdc84, 0x0fffdc00,	0x3fffdc04, 0xffffdc84, 0xffffdc84, 0xffffdc05,	/* burst read    (offset 0x08 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* single write  (offset 0x18 in upm ram) */	0x8fffd004, 0x0fffd084, 0x0fffd084, 0x3fffd000,	0xffffd084, 0xffffd084, 0xffffd005, _NOT_USED_,	/* burst write   (offset 0x20 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* refresh       (offset 0x30 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* exception     (offset 0x3C in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,};/* dsp hpi upm ram table * works fine for noninc access, failes on incremental. * - removed first word */const uint dsp_table_fast[] ={	/* single read   (offset  0x00 in upm ram) */	0x8fffdc04, 0x0fffdc04, 0x0fffdc00, 0x3fffdc04,	0xffffdc05, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* burst read    (offset 0x08 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* single write  (offset 0x18 in upm ram) */	0x8fffd004, 0x0fffd004, 0x3fffd000, 0xffffd005,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* burst write   (offset 0x20 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* refresh       (offset 0x30 in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,	/* exception     (offset 0x3C in upm ram) */	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,};#ifdef CONFIG_SPC1920_HPI_TEST#undef HPI_TEST_OSZI#define HPI_TEST_CHUNKSIZE	0x1000#define HPI_TEST_PATTERN	0x00000000#define HPI_TEST_START		0x0#define HPI_TEST_END		0x30000#define TINY_AUTOINC_DATA_SIZE 16 /* 32bit words */#define TINY_AUTOINC_BASE_ADDR 0x0static int hpi_activate(void);#if 0static void hpi_inactivate(void);#endifstatic void dsp_reset(void);static int hpi_write_inc(u32 addr, u32 *data, u32 count);static int hpi_read_inc(u32 addr, u32 *buf, u32 count);static int hpi_write_noinc(u32 addr, u32 data);static u32 hpi_read_noinc(u32 addr);int hpi_test(void);static int hpi_write_addr_test(u32 addr);static int hpi_read_write_test(u32 addr, u32 data);#ifdef DO_TINY_TESTstatic int hpi_tiny_autoinc_test(void);#endif /* DO_TINY_TEST */#endif /* CONFIG_SPC1920_HPI_TEST *//* init the host port interface on UPMA */int hpi_init(void){	volatile immap_t *immr = (immap_t *) CFG_IMMR;	volatile memctl8xx_t *memctl = &immr->im_memctl;	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;	upmconfig(UPMA, (uint *)dsp_table_slow, sizeof(dsp_table_slow)/sizeof(uint));	udelay(100);	memctl->memc_mamr = CFG_MAMR;	memctl->memc_or3 = CFG_OR3;	memctl->memc_br3 = CFG_BR3;	/* reset dsp */	dsp_reset();	/* activate hpi switch*/	pld->dsp_hpi_on = 0x1;	udelay(100);	return 0;}#ifdef CONFIG_SPC1920_HPI_TEST/* activate the Host Port interface */static int hpi_activate(void){	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;	/* turn on hpi */	pld->dsp_hpi_on = 0x1;	udelay(5);	/* turn on the power EN_DSP_POWER high*/	/* currently always on TBD */	/* setup hpi control register */	HPI_HPIC_1 = (u16) 0x0008;	HPI_HPIC_2 = (u16) 0x0008;	udelay(100);	return 0;}#if 0/* turn off the host port interface */static void hpi_inactivate(void){	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;	/* deactivate hpi */	pld->dsp_hpi_on = 0x0;	/* reset the dsp */	/* pld->dsp_reset = 0x0; */	/* turn off the power EN_DSP_POWER# high*/	/* currently always on TBD */}#endif/* reset the DSP */static void dsp_reset(void){	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;	pld->dsp_reset = 0x1;	pld->dsp_hpi_on = 0x0;	udelay(300000);	pld->dsp_reset = 0x0;	pld->dsp_hpi_on = 0x1;}/* write using autoinc (count is number of 32bit words) */static int hpi_write_inc(u32 addr, u32 *data, u32 count){	int i;	u16 addr1, addr2;	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */	addr2 = (u16) (addr & 0xffff);	/* write address */	HPI_HPIA_1 = addr1;	HPI_HPIA_2 = addr2;	debugX(4, "writing from data=0x%x to 0x%x\n", data, (data+count));	for(i=0; i<count; i++) {		HPI_HPID_INC_1 = (u16) ((data[i] >> 16) & 0xffff);		HPI_HPID_INC_2 = (u16) (data[i] & 0xffff);		debugX(4, "hpi_write_inc: data1=0x%x, data2=0x%x\n",		       (u16) ((data[i] >> 16) & 0xffff),		       (u16) (data[i] & 0xffff));	}#if 0	while(data_ptr < (u16*) (data + count)) {		HPI_HPID_INC_1 = *(data_ptr++);		HPI_HPID_INC_2 = *(data_ptr++);	}#endif	/* return number of bytes written */	return count;}/* * read using autoinc (count is number of 32bit words) */static int hpi_read_inc(u32 addr, u32 *buf, u32 count){	int i;	u16 addr1, addr2, data1, data2;	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */	addr2 = (u16) (addr & 0xffff);	/* write address */	HPI_HPIA_1 = addr1;	HPI_HPIA_2 = addr2;	for(i=0; i<count; i++) {		data1 = HPI_HPID_INC_1;		data2 = HPI_HPID_INC_2;		debugX(4, "hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);		buf[i] = (((u32) data1) << 16) | (data2 & 0xffff);	}#if 0	while(buf_ptr < (u16*) (buf + count)) {		*(buf_ptr++) = HPI_HPID_INC_1;		*(buf_ptr++) = HPI_HPID_INC_2;	}#endif	/* return number of bytes read */	return count;}/* write to non- auto inc regs */static int hpi_write_noinc(u32 addr, u32 data){	u16 addr1, addr2, data1, data2;	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */	addr2 = (u16) (addr & 0xffff);	/* printf("hpi_write_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */	HPI_HPIA_1 = addr1;	HPI_HPIA_2 = addr2;	data1 = (u16) ((data >> 16) & 0xffff);	data2 = (u16) (data & 0xffff);

⌨️ 快捷键说明

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