📄 quasar.c
字号:
/* * linux/arch/arm/mach-jasper/quasar.c * for JASPER / EM8550 with QUASAR 4 * Created 09/19/2002 Ho Lee * Copyright 2002 Sigma Designs, Inc */#ifdef __KERNEL__#include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h>#include <asm/arch/quasar.h>#include <asm/system.h>#else // for boot loader#include "quasar.h"#define EXPORT_SYMBOL(x)#define __init#endifvoid quasar_init(void);void quasar_init_risc(void);void quasar_init_2MB_SDRAM(void);void quasar_init_4MB_SDRAM(void);void quasar_init_2MB_EDORAM(void);void quasar_lbc_init(void);unsigned int quasar_lbc_readl(unsigned int addr);void quasar_lbc_writel(unsigned int addr, unsigned int data);void quasar_init_irq(void);EXPORT_SYMBOL(quasar_lbc_readl);EXPORT_SYMBOL(quasar_lbc_writel);EXPORT_SYMBOL(quasar_enable_irq);EXPORT_SYMBOL(quasar_disable_irq);EXPORT_SYMBOL(quasar_irq_enabled);EXPORT_SYMBOL(quasar_irq_pending);EXPORT_SYMBOL(quasar_clear_irq);//// QUASAR Initialization//void __init quasar_init(void){ quasar_init_risc(); quasar_init_4MB_SDRAM(); quasar_writel_reg(Q4_RISC_reset_run, 0x00); // RISC unreset, stop quasar_writel_reg(Q4_MISC_reset1, 0x1818); quasar_writel_reg(Q4_MISC_reset1, 0x1800); quasar_lbc_init();}void __init quasar_init_risc(void){ unsigned int temp; // QUASAR4 Enable quasar_writel_reg(0x1000 + RBUS_reset_run, 0x00); // Unreset RST0-7 quasar_writel_reg(0x1000 + RISC_reset0, 0xffff); quasar_writel_reg(0x1000 + RISC_reset0, 0xff00); // Unreset RST8-15 quasar_writel_reg(0x1000 + RISC_reset1, 0xffff); quasar_writel_reg(0x1000 + RISC_reset1, 0xff00); // Initialize SDRAM quasar_writel_reg(0x1000 + DRAM_config, (DRSIZE << 3) | TIMING | (REFRESH_PEROID << 5)); // Program FIFO Size quasar_writel_reg(0x1000 + DRAM_fifosize0, 0x5555); quasar_writel_reg(0x1000 + DRAM_fifosize1, 0x055a); quasar_writel_reg(0x1000 + DRAM_fifosize2, 0x0080); // Unreset DRAM controller by clearing bit 15 temp = quasar_readl_reg(0x1000 + DRAM_pllcontrol); quasar_writel_reg(0x1000 + DRAM_pllcontrol, temp & 0x7fff);}void __init quasar_init_2MB_SDRAM(void){ quasar_writel_reg(0x1000 + DRAM_config, 0x40); // 1 * SDRAM 2Mx16}void __init quasar_init_4MB_SDRAM(void){ quasar_writel_reg(0x1000 + DRAM_config, 0x58); // 1 * SDRAM 4Mx16}void __init quasar_init_2MB_EDORAM(void){ quasar_writel_reg(0x1000 + DRAM_config, 0x40); // 1 * EDO RAM 512kx32}//// QUASAR Local Bus Controller//void __init quasar_lbc_init(void){ quasar_writel(QUASAR_LBC_CONFIG0, 0x0002); // set Streammachine if; MSB first for rd/wr; no auto incr quasar_writel(QUASAR_LBC_CONFIG1, 0x0000); // prim. device; HPGIO input}unsigned int quasar_lbc_readl(unsigned int addr){ unsigned int status, data; quasar_writel(QUASAR_LBC_READ_ADDR, addr); while ((status = quasar_readl(QUASAR_LBC_STATUS)) & 0x01) ; data = quasar_readl(QUASAR_LBC_READ_DATA);//PrintFormat("[qusara.c] quasar_lbc_readl, addr=0x%x, data=0x%x\n", addr, data); return data;}void quasar_lbc_writel(unsigned int addr, unsigned int data){ unsigned int status;//PrintFormat("[qusara.c] quasar_lbc_writel, addr=0x%x, data=0x%x\n", addr, data); quasar_writel(QUASAR_LBC_WRITE_ADDR, addr); quasar_writel(QUASAR_LBC_WRITE_DATA, data); while ((status = quasar_readl(QUASAR_LBC_STATUS)) & 0x02) ;//PrintFormat("[qusara.c] quasar_lbc_writel complete\n");}//// Interrupt handling//void __init quasar_init_irq(void){ unsigned irqstat; // QUASAR LBC interrupt controller irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); irqstat &= 0x000f; // disable all interrupt, rising edge // clear all pending IRQ quasar_writel(QUASAR_LBC_INTERRUPT, irqstat); // HOST interrupt controller : enable Q2H_LOC interrupt irqstat = __raw_readl(JASPER_INT_CONTROLLER_BASE + INT_INTEN); irqstat |= Q2H_LOC_INT; __raw_writel(irqstat, JASPER_INT_CONTROLLER_BASE + INT_INTEN);}// enable specified IRQ from LBC// irq : 0 - 3// falling_edge : 0 = rising edge, 1 = falling edge// return previous status of enable bitint quasar_enable_irq(int irq, int falling_edge){ unsigned int irqstat; int saved_enable; if (irq < 0 || irq > 3) return -1; irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); saved_enable = (irqstat & (irq << 4)) ? 1 : 0; irqstat |= (1 << (4 + irq)); // set enable bit if (falling_edge) irqstat |= (1 << (8 + irq)); // set polarity bit : falling edge else irqstat &= ~(1 << (8 + irq)); // clear polarity bit : rising edge irqstat &= ~0x000f; // preserve IRQ pending quasar_writel(QUASAR_LBC_INTERRUPT, irqstat); return saved_enable;}int quasar_disable_irq(int irq){ unsigned int irqstat; int saved_enable; if (irq < 0 || irq > 3) return -1; irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); saved_enable = (irqstat & (irq << 4)) ? 1 : 0; irqstat &= ~(1 << (4 + irq)); // set enable bit irqstat &= ~0x000f; // preserve IRQ pending quasar_writel(QUASAR_LBC_INTERRUPT, irqstat); return saved_enable;}int quasar_irq_enabled(int irq){ unsigned int irqstat; if (irq < 0 || irq > 3) return -1; irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); return (irqstat & (1 << (4 + irq))) ? 1 : 0;}// return if the specified IRQ is pendingint quasar_irq_pending(int irq){ unsigned int irqstat; if (irq < 0 || irq > 3) return -1; irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); return (irqstat & (1 << irq)) ? 1 : 0;}// clear the specified IRQ pending bitvoid quasar_clear_irq(int irq){ unsigned int irqstat; if (irq < 0 || irq > 3) return; irqstat = quasar_readl(QUASAR_LBC_INTERRUPT); if (irqstat & (1 << irq)) { irqstat &= ~0x000f; // preserve IRQ pending irqstat |= (1 << irq); quasar_writel(QUASAR_LBC_INTERRUPT, irqstat); }}//// DMA Handling//// addr : address of memory where the data will be written// counter : number of bytesvoid quasar_setup_q2h_dma(int master_enable, unsigned int addr, unsigned int counter){ quasar_writel_reg(Q4_Q2H_master_enable, master_enable ? 1 : 0); quasar_writel_reg(Q4_Q2H_hostmem_addr_lo, addr & 0x0000ffff); quasar_writel_reg(Q4_Q2H_hostmem_addr_hi, (addr & 0xffff0000) >> 16); quasar_writel_reg(Q4_Q2H_byte_counter, counter);}// addr : address to read// counter : number of bytesvoid quasar_setup_lbc_readfifo(int fifo, unsigned int addr, unsigned int counter){ quasar_writel_reg(Q4_LBC_config0, 0x1006); quasar_writel_reg(Q4_LBC_read_fifo0_access + (fifo * 2), addr); quasar_writel_reg(Q4_LBC_read_fifo0_cnt + (fifo * 2), counter);}void quasar_cleanup_lbc_fifo(void){ quasar_writel_reg(Q4_LBC_config0, 0x0002);}//// Miscellaneous//void quasar_flush_cache_all(void){ unsigned long flags; local_irq_save(flags); __clf(); __asm__( "mcr p15, 0, %0, c7, c10, 0\n" // write-back data cache "mcr p15, 0, %0, c7, c6, 0\n" // flush data cache "mcr p15, 0, %0, c7, c5, 0\n" // flush instruction cache : : "r" (0) ); local_irq_restore(flags);}void quasar_flush_cache_data(void){ unsigned long flags; local_irq_save(flags); __clf(); __asm__( "mcr p15, 0, %0, c7, c10, 0\n" // write-back data cache "mcr p15, 0, %0, c7, c6, 0\n" // flush data cache : : "r" (0) ); local_irq_restore(flags);}void quasar_flush_cache_data_region(unsigned int from, unsigned int to){ unsigned long flags; from &= ~0x0f; to &= ~0x0f; local_irq_save(flags); __clf(); for (; from <= to; from += 0x10) { __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 1\n" "mcr p15, 0, %0, c7, c6, 1\n" : : "r" (from) ); } local_irq_restore(flags);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -