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 + -
显示快捷键?