From 010afa92be383ee2541346564fd77e2d47114e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Wed, 2 Nov 2016 06:26:04 +0000 Subject: [PATCH] add more Radeon functionality --- BaS_gcc/BaS_gcc.files | 2 + BaS_gcc/Makefile | 3 + BaS_gcc/bas.lk.in | 3 + BaS_gcc/flash/flash.c | 2 + BaS_gcc/include/debug.h | 3 + BaS_gcc/include/fb.h | 16 -- BaS_gcc/include/i2c.h | 3 +- BaS_gcc/include/m5484l.h | 2 +- BaS_gcc/include/radeonfb.h | 25 +- BaS_gcc/include/util.h | 2 +- BaS_gcc/include/video.h | 1 + BaS_gcc/include/wait.h | 3 + BaS_gcc/radeon/i2c-algo-bit.c | 474 ++++++++++++++++++++++++++++++++ BaS_gcc/radeon/radeon_base.c | 31 ++- BaS_gcc/radeon/radeon_i2c.c | 97 ++++--- BaS_gcc/radeon/radeon_monitor.c | 20 +- BaS_gcc/sys/BaS.c | 4 +- BaS_gcc/util/wait.c | 15 + BaS_gcc/video/fbmon.c | 278 ++++++++----------- BaS_gcc/video/video.c | 17 +- BaS_gcc/x86emu/x86biosemu.c | 39 ++- BaS_gcc/x86emu/x86pcibios.c | 7 +- 22 files changed, 774 insertions(+), 273 deletions(-) create mode 100644 BaS_gcc/radeon/i2c-algo-bit.c diff --git a/BaS_gcc/BaS_gcc.files b/BaS_gcc/BaS_gcc.files index 10ad6e5..7db5a35 100644 --- a/BaS_gcc/BaS_gcc.files +++ b/BaS_gcc/BaS_gcc.files @@ -893,3 +893,5 @@ tos/vmem_test/sources/vmem_test.c tos/vmem_test/Makefile tos/Makefile radeon/radeon_i2c.c +basflash.lk.in +radeon/i2c-algo-bit.c diff --git a/BaS_gcc/Makefile b/BaS_gcc/Makefile index 26fbb0f..f531e97 100644 --- a/BaS_gcc/Makefile +++ b/BaS_gcc/Makefile @@ -41,6 +41,7 @@ CFLAGS= -Wall \ -O2 \ -fomit-frame-pointer \ -ffreestanding \ + -fno-strict-aliasing \ -fleading-underscore \ -Winline \ -Wa,--register-prefix-optional \ @@ -134,6 +135,8 @@ CSRCS= \ videl.c \ video.c \ \ + i2c-algo-bit.c \ + \ radeon_base.c \ radeon_accel.c \ radeon_cursor.c \ diff --git a/BaS_gcc/bas.lk.in b/BaS_gcc/bas.lk.in index 342b704..0d14f05 100644 --- a/BaS_gcc/bas.lk.in +++ b/BaS_gcc/bas.lk.in @@ -104,10 +104,13 @@ SECTIONS OBJDIR/x86pcibios.o(.text) OBJDIR/x86biosemu.o(.text) + OBJDIR/i2c-algo-bit.o(.text) + OBJDIR/radeon_base.o(.text) OBJDIR/radeon_accel.o(.text) OBJDIR/radeon_cursor.o(.text) OBJDIR/radeon_monitor.o(.text) + OBJDIR/radeon_i2c.o(.text) OBJDIR/xhdi_sd.o(.text) OBJDIR/xhdi_interface.o(.text) diff --git a/BaS_gcc/flash/flash.c b/BaS_gcc/flash/flash.c index 6442015..658c10a 100644 --- a/BaS_gcc/flash/flash.c +++ b/BaS_gcc/flash/flash.c @@ -193,6 +193,8 @@ void amd_flash_sector_erase(int n) { volatile AMD_FLASH_CELL status; + (void) num_flash_areas; /* to make compiler happy */ + pFlash[0x555] = AMD_FLASH_CMD_DATA(0xAA); pFlash[0x2AA] = AMD_FLASH_CMD_DATA(0x55); pFlash[0x555] = AMD_FLASH_CMD_DATA(0x80); diff --git a/BaS_gcc/include/debug.h b/BaS_gcc/include/debug.h index 9ee9cad..8896887 100644 --- a/BaS_gcc/include/debug.h +++ b/BaS_gcc/include/debug.h @@ -2,6 +2,9 @@ #define DEBUG_H #ifdef DEBUG +#include "bas_types.h" +#include "bas_printf.h" + #define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0) #else #define dbg(format, arg...) do {;} while (0) diff --git a/BaS_gcc/include/fb.h b/BaS_gcc/include/fb.h index 4121db4..c0fb6c8 100644 --- a/BaS_gcc/include/fb.h +++ b/BaS_gcc/include/fb.h @@ -545,22 +545,6 @@ struct fb_videomode extern const struct fb_videomode vesa_modes[]; - -/* timer FIXME: doesn't really fit yet to Coldfire timings */ - -#if defined(MACHINE_FIREBEE) -#define US_TO_TIMER(a) (((a) * 256) / 5000) -#define TIMER_TO_US(a) (((a) * 5000) / 256) -#elif defined(MACHINE_M5484LITE) -#define US_TO_TIMER(a) ((a) * 100) -#define TIMER_TO_US(a) ((a) / 100) -#elif defined(MACHINE_M54455) -#define US_TO_TIMER(a) (a) -#define TIMER_TO_US(a) (a) -#else -#error Unknown machine! -#endif - extern void start_timeout(void); extern int end_timeout(long msec); extern void mdelay(long msec); diff --git a/BaS_gcc/include/i2c.h b/BaS_gcc/include/i2c.h index ac44287..4645f89 100644 --- a/BaS_gcc/include/i2c.h +++ b/BaS_gcc/include/i2c.h @@ -84,6 +84,7 @@ struct i2c_msg unsigned char *buf; /* pointer to msg data */ }; +/* extern void i2c_init(void); extern void i2c_set_frequency(int hz); extern int i2c_read(int address, char *data, int lengt, bool repeated); @@ -92,5 +93,5 @@ extern int i2c_write(int address, const char *data, int length, bool repeated); extern int i2c_write_byte(int data); extern void i2c_start(void); extern void i2c_stop(void); - +*/ #endif /* _I2C_H */ diff --git a/BaS_gcc/include/m5484l.h b/BaS_gcc/include/m5484l.h index 4876f5e..b1ddb2e 100644 --- a/BaS_gcc/include/m5484l.h +++ b/BaS_gcc/include/m5484l.h @@ -27,7 +27,7 @@ * Author: Markus Fröschle */ -#define SYSCLK 100000 +#define SYSCLK 100000UL #define BOOTFLASH_BASE_ADDRESS 0xe0000000 #define BOOTFLASH_SIZE 0x400000 /* LITEKIT has 4MB flash */ diff --git a/BaS_gcc/include/radeonfb.h b/BaS_gcc/include/radeonfb.h index 5de0923..6f12093 100644 --- a/BaS_gcc/include/radeonfb.h +++ b/BaS_gcc/include/radeonfb.h @@ -1,10 +1,6 @@ #ifndef __RADEONFB_H__ #define __RADEONFB_H__ -#ifdef CONFIG_FB_RADEON_I2C -#undef CONFIG_FB_RADEON_I2C -#endif - #include #include "pci.h" #include "mod_devicetable.h" @@ -14,6 +10,7 @@ #include "i2c-algo-bit.h" #include "util.h" /* for swpX() */ #include "wait.h" +#include "video.h" //#include "radeon_theatre.h" @@ -388,7 +385,7 @@ struct radeonfb_info int32_t is_IGP; int32_t reversed_DAC; int32_t reversed_TMDS; - struct panel_info panel_info; + struct panel_info panel_info; int32_t mon1_type; uint8_t *mon1_EDID; struct fb_videomode *mon1_modedb; @@ -489,17 +486,17 @@ extern uint32_t __INPLL(struct radeonfb_info *rinfo, uint32_t addr); extern void __OUTPLL(struct radeonfb_info *rinfo, uint32_t index, uint32_t val); extern void __OUTPLLP(struct radeonfb_info *rinfo, uint32_t index, uint32_t val, uint32_t mask); -#define INREG8(addr) *((uint8_t *)(rinfo->mmio_base + addr)) -#define INREG16(addr) swpw(*(uint16_t *)(rinfo->mmio_base + addr)) -#define INREG(addr) swpl(*(uint32_t *)(rinfo->mmio_base + addr)) -#define OUTREG8(addr, val) (*((uint8_t *)(rinfo->mmio_base + addr)) = val) -#define OUTREG16(addr, val) (*((uint16_t *)(rinfo->mmio_base + addr)) = swpw((uint32_t) val)) -#define OUTREG(addr, val) (*((uint32_t *)(rinfo->mmio_base + addr)) = swpl((uint32_t) val)) +#define INREG8(addr) *((volatile uint8_t *)(rinfo->mmio_base + addr)) +#define INREG16(addr) swpw(*(volatile uint16_t *)(rinfo->mmio_base + addr)) +#define INREG(addr) swpl(*(volatile uint32_t *)(rinfo->mmio_base + addr)) +#define OUTREG8(addr, val) (*((volatile uint8_t *)(rinfo->mmio_base + addr)) = val) +#define OUTREG16(addr, val) (*((volatile uint16_t *)(rinfo->mmio_base + addr)) = swpw((uint32_t) val)) +#define OUTREG(addr, val) (*((volatile uint32_t *)(rinfo->mmio_base + addr)) = swpl((uint32_t) val)) extern int32_t *tab_funcs_pci; -#define BIOS_IN8(v) (* ((uint8_t *) rinfo->bios_seg_phys + v)) -#define BIOS_IN16(v) (swpw(*(uint16_t *) ((uint8_t *) rinfo->bios_seg_phys + v))) -#define BIOS_IN32(v) (swpl(*(uint32_t *) ((uint8_t *) rinfo->bios_seg_phys + v))) +#define BIOS_IN8(v) (* ((volatile uint8_t *) rinfo->bios_seg_phys + v)) +#define BIOS_IN16(v) (swpw(*(volatile uint16_t *) ((uint8_t *) rinfo->bios_seg_phys + v))) +#define BIOS_IN32(v) (swpl(*(volatile uint32_t *) ((uint8_t *) rinfo->bios_seg_phys + v))) #define ADDRREG(addr) ((volatile uint32_t *)(rinfo->mmio_base + (addr))) #define OUTREGP(addr, val, mask) _OUTREGP(rinfo, addr, val, mask) diff --git a/BaS_gcc/include/util.h b/BaS_gcc/include/util.h index 355c1ac..6ec6d17 100644 --- a/BaS_gcc/include/util.h +++ b/BaS_gcc/include/util.h @@ -43,7 +43,7 @@ static inline uint16_t swpw(uint16_t w) * swap endianess of val, 32 bits only. * e.g. ABCD => DCBA */ -static inline uint32_t swpl(uint32_t l) +inline uint32_t swpl(uint32_t l) { return ((l & 0xff000000) >> 24) | ((l & 0x00ff0000) >> 8) | ((l & 0x0000ff00) << 8) | (l << 24); diff --git a/BaS_gcc/include/video.h b/BaS_gcc/include/video.h index 636a225..e02f25a 100644 --- a/BaS_gcc/include/video.h +++ b/BaS_gcc/include/video.h @@ -3,6 +3,7 @@ #include #include "bas_printf.h" +#define CONFIG_FB_RADEON_I2C extern void video_init(void); diff --git a/BaS_gcc/include/wait.h b/BaS_gcc/include/wait.h index 90b2736..20e9eea 100644 --- a/BaS_gcc/include/wait.h +++ b/BaS_gcc/include/wait.h @@ -55,4 +55,7 @@ extern bool waitfor(uint32_t us, checker_func condition); extern uint32_t get_timer(void); extern void wait_ms(uint32_t ms); +#define US_TO_TIMER(a) ((a) * SYSCLK) / 1000000UL +#define TIMER_TO_US(a) ((a) * 1000000UL) / SYSCLK) + #endif /* _WAIT_H_ */ diff --git a/BaS_gcc/radeon/i2c-algo-bit.c b/BaS_gcc/radeon/i2c-algo-bit.c new file mode 100644 index 0000000..86e4d25 --- /dev/null +++ b/BaS_gcc/radeon/i2c-algo-bit.c @@ -0,0 +1,474 @@ +/* ------------------------------------------------------------------------- */ +/* i2c-algo-bit.c i2c driver algorithms for bit-shift adapters */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 1995-2000 Simon G. Vogl + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Frodo Looijaard , Kyösti Mälkki + and Jean Delvare */ + +#include "wait.h" +#include "i2c.h" +#include "i2c-algo-bit.h" + +#ifndef NULL +#define NULL ((void *)0) +#endif + +// #define DEBUG +#include "debug.h" + +extern void start_timeout(void); +extern int end_timeout(long msec); +extern void udelay(long usec); + +/* --- setting states on the bus with the right timing: --------------- */ + +#define setsda(adap,val) adap->setsda(adap->data, val) +#define setscl(adap,val) adap->setscl(adap->data, val) +#define getsda(adap) adap->getsda(adap->data) +#define getscl(adap) adap->getscl(adap->data) + +static inline void sdalo(struct i2c_algo_bit_data *adap) +{ + setsda(adap,0); + wait_us(adap->udelay); +} + +static inline void sdahi(struct i2c_algo_bit_data *adap) +{ + setsda(adap,1); + wait_us(adap->udelay); +} + +static inline void scllo(struct i2c_algo_bit_data *adap) +{ + setscl(adap,0); + wait_us(adap->udelay); +} + +/* + * Raise scl line, and do checking for delays. This is necessary for slower + * devices. + */ +static inline int sclhi(struct i2c_algo_bit_data *adap) +{ + setscl(adap,1); + /* Not all adapters have scl sense line... */ + if(adap->getscl == NULL ) + { + wait_us(adap->udelay); + return 0; + } + start_timeout(); + while(! getscl(adap)) + { + /* the hw knows how to read the clock line, + * so we wait until it actually gets high. + * This is safer as some chips may hold it low + * while they are processing data internally. + */ + if(end_timeout((long)adap->timeout)) + return -110; + } + wait_us(adap->udelay); + return 0; +} + + +/* --- other auxiliary functions -------------------------------------- */ +void i2c_start(struct i2c_algo_bit_data *adap) +{ + /* assert: scl, sda are high */ + sdalo(adap); + scllo(adap); +} + +static void i2c_repstart(struct i2c_algo_bit_data *adap) +{ + /* scl, sda may not be high */ + setsda(adap,1); + sclhi(adap); + wait_ms(adap->udelay); + sdalo(adap); + scllo(adap); +} + +static void i2c_stop(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdalo(adap); + sclhi(adap); + sdahi(adap); +} + +/* send a byte without start cond., look for arbitration, + check ackn. from slave */ +/* returns: + * 1 if the device acknowledged + * 0 if the device did not ack + * -ETIMEDOUT if an error occurred (while raising the scl line) + */ +static int i2c_outb(struct i2c_adapter *i2c_adap, char c) +{ + int i; + int sb; + int ack; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + /* assert: scl is low */ + + for (i = 7; i >= 0; i--) + { + sb = c & ( 1 << i ); + setsda(adap,sb); + wait_ms(adap->udelay); + if(sclhi(adap)<0) + { /* timed out */ + sdahi(adap); /* we don't want to block the net */ +#ifdef DEBUG + dbg("ETIMEDOUT\r\n"); +#endif + return -110; + }; + /* do arbitration here: + * if ( sb && ! getsda(adap) ) -> ouch! Get out of here. + */ + setscl(adap, 0 ); + wait_us(adap->udelay); + } + sdahi(adap); + if(sclhi(adap)<0) + { + /* timeout */ +#ifdef DEBUG + dbg("ETIMEDOUT\r\n"); +#endif + return -110; + } + /* read ack: SDA should be pulled down by slave */ + ack = getsda(adap); /* ack: sda is pulled low ->success. */ + scllo(adap); +#ifdef DEBUG + dbg("0x%02x, ack=0x%02x\r\n", (unsigned long)(c & 0xff), ack); +#endif + return 0==ack; /* return 1 if device acked */ + /* assert: scl is low (sda undef) */ +} + +static int i2c_inb(struct i2c_adapter *i2c_adap) +{ + /* read byte via i2c port, without start/stop sequence */ + /* acknowledge is sent in i2c_read. */ + int i; + unsigned char indata=0; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + /* assert: scl is low */ + sdahi(adap); + for(i=0;i<8;i++) + { + if(sclhi(adap)<0) + { + /* timeout */ +#ifdef DEBUG + dbg("i2c_inb TIMEDOUT\r\n"); +#endif + return -110; + } + indata *= 2; + if(getsda(adap)) + indata |= 0x01; + scllo(adap); + } + /* assert: scl is low */ +#ifdef DEBUG + dbg("0x%02x\r\n", (unsigned long)(indata & 0xff)); +#endif + return (int) (indata & 0xff); +} + +/* + * Sanity check for the adapter hardware - check the reaction of + * the bus lines only if it seems to be idle. + */ +static int test_bus(struct i2c_algo_bit_data *adap) +{ + int scl,sda; + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + if(!scl || !sda ) + goto bailout; + sdalo(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + if(sda !=0 || scl == 0) + goto bailout; + sdahi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + if (sda == 0 || scl ==0) + goto bailout; + scllo(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?0:getscl(adap)); + if(scl !=0 || sda == 0) + goto bailout; + sclhi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + if(scl == 0 || sda ==0) + goto bailout; + return 0; +bailout: + sdahi(adap); + sclhi(adap); + return -110; +} + +/* ----- Utility functions + */ + +/* try_address tries to contact a chip for a number of + * times before it gives up. + * return values: + * 1 chip answered + * 0 chip did not answer + * -x transmission error + */ +static inline int try_address(struct i2c_adapter *i2c_adap, + unsigned char addr, int retries) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i,ret = -1; + for(i=0;i<=retries;i++) + { + ret = i2c_outb(i2c_adap,addr); + if(ret==1) + break; /* success! */ + i2c_stop(adap); + wait_us(5); + if(i==retries) /* no success */ + break; + i2c_start(adap); + wait_us(adap->udelay); + } + return ret; +} + +static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + char c; + const char *temp = (const char *)msg->buf; + int count = msg->len; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int retval; + int wrcount=0; + while(count > 0) + { + c = *temp; + retval = i2c_outb(i2c_adap,c); + if((retval>0) || (nak_ok && (retval==0))) + { /* ok or ignored NAK */ + count--; + temp++; + wrcount++; + } + else + { /* arbitration or no acknowledge */ + i2c_stop(adap); + return (retval<0)? retval : -110; + /* got a better one ?? */ + } + } + return wrcount; +} + +static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int inval; + int rdcount=0; /* counts bytes read */ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + char *temp = (char *)msg->buf; + int count = msg->len; + while(count > 0) + { + inval = i2c_inb(i2c_adap); + if(inval>=0) + { + *temp = inval; + rdcount++; + } + else + /* read timed out */ + break; + temp++; + count--; + if(msg->flags & I2C_M_NO_RD_ACK) + continue; + if( count > 0 ) + /* send ack */ + sdalo(adap); + else + sdahi(adap); /* neg. ack on last byte */ + if(sclhi(adap)<0) + { /* timeout */ + sdahi(adap); + return -1; + }; + scllo(adap); + sdahi(adap); + } + return rdcount; +} + +/* doAddress initiates the transfer by generating the start condition (in + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: + * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -EREMOTEIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + unsigned char addr; + int ret, retries; + retries = nak_ok ? 0 : i2c_adap->retries; + if(flags & I2C_M_TEN) + { + /* a ten bit address */ + addr = 0xf0 | (( msg->addr >> 7) & 0x03); + /* try extended address code...*/ + ret = try_address(i2c_adap, addr, retries); + if((ret != 1) && !nak_ok) + return -1; + /* the remaining 8 bit address */ + ret = i2c_outb(i2c_adap,msg->addr & 0x7f); + if((ret != 1) && !nak_ok) + /* the chip did not ack / xmission error occurred */ + return -1; + if(flags & I2C_M_RD) + { + i2c_repstart(adap); + /* okay, now switch into reading mode */ + addr |= 0x01; + ret = try_address(i2c_adap, addr, retries); + if ((ret!=1) && !nak_ok) + return -1; + } + } + else + { /* normal 7bit address */ + addr = ( msg->addr << 1 ); + if(flags & I2C_M_RD ) + addr |= 1; + if(flags & I2C_M_REV_DIR_ADDR ) + addr ^= 1; + ret = try_address(i2c_adap, addr, retries); + if((ret!=1) && !nak_ok) + return -1; + } + return 0; +} + +static int bit_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +{ + struct i2c_msg *pmsg; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i,ret; + unsigned short nak_ok; + i2c_start(adap); + for(i=0;iflags & I2C_M_IGNORE_NAK; + if(!(pmsg->flags & I2C_M_NOSTART)) + { + if(i) + i2c_repstart(adap); + ret = bit_doAddress(i2c_adap, pmsg); + if((ret != 0) && !nak_ok) + return (ret<0) ? ret : -1; + } + if(pmsg->flags & I2C_M_RD ) + { + /* read bytes into buffer*/ + ret = readbytes(i2c_adap, pmsg); + if(ret < pmsg->len) + return (ret<0)? ret : -1; + } + else + { + /* write bytes from buffer */ + ret = sendbytes(i2c_adap, pmsg); + if(ret < pmsg->len ) + return (ret<0) ? ret : -1; + } + } + i2c_stop(adap); + return num; +} + +/* -----exported algorithm data: ------------------------------------- */ + +static struct i2c_algorithm i2c_bit_algo = { + .master_xfer = bit_xfer, +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_bit_add_bus(struct i2c_adapter *adap) +{ + struct i2c_algo_bit_data *bit_adap = adap->algo_data; + if(1) + { + int ret = test_bus(bit_adap); + if(ret<0) + return -1; + } + /* register new adapter to i2c module... */ + adap->algo = &i2c_bit_algo; + adap->timeout = 100; /* default values, should */ + adap->retries = 3; /* be replaced by defines */ + return 0; +} + +int i2c_bit_del_bus(struct i2c_adapter *adap) +{ + return(0); +} + +/* ---------------------------------------------------- + * the functional interface to the i2c busses. + * ---------------------------------------------------- + */ + +int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) +{ + int ret; + if(adap->algo->master_xfer) + { + ret = adap->algo->master_xfer(adap,msgs,num); + return ret; + } + else + return -1; +} diff --git a/BaS_gcc/radeon/radeon_base.c b/BaS_gcc/radeon/radeon_base.c index 226683c..c93ee4d 100644 --- a/BaS_gcc/radeon/radeon_base.c +++ b/BaS_gcc/radeon/radeon_base.c @@ -311,6 +311,7 @@ uint32_t __INPLL(struct radeonfb_info *rinfo, uint32_t addr) radeon_pll_errata_after_index(rinfo); data = INREG(CLOCK_CNTL_DATA); radeon_pll_errata_after_data(rinfo); + return data; } @@ -339,7 +340,7 @@ static __inline int round_div(int num, int den) static __inline uint32_t read_vline_crnt(struct radeonfb_info *rinfo) { - return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF); + return (INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF; } static int radeon_map_ROM(struct radeonfb_info *rinfo) @@ -481,6 +482,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) uint32_t stop_tv; int timeout = 0; int ipl; + uint32_t vline; /* * Ugh, we cut interrupts, bad bad bad, but we want some precision @@ -488,15 +490,15 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) */ ipl = set_ipl(0); - dbg("radeon_probe_pll_params\r\n"); + dbg("\r\n"); /* Flush PCI buffers ? */ tmp = INREG16(DEVICE_ID); start_tv = get_timer(); - while (read_vline_crnt(rinfo) != 0) + while ((vline = read_vline_crnt(rinfo)) != 0) { - if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ + if ((start_tv - get_timer()) > US_TO_TIMER(10000000UL)) /* 10 sec */ { timeout = 1; dbg("timeout\r\n"); @@ -509,7 +511,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) start_tv = get_timer(); while (read_vline_crnt(rinfo) == 0) { - if ((get_timer() - start_tv) > US_TO_TIMER(1000000UL)) /* 1 sec */ + if ((start_tv - get_timer()) > US_TO_TIMER(1000000UL)) /* 1 sec */ { timeout = 1; dbg("timeout2\r\n"); @@ -521,7 +523,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) { while (read_vline_crnt(rinfo) != 0) { - if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ + if ((start_tv - get_timer()) > US_TO_TIMER(10000000UL)) /* 10 sec */ { timeout = 1; dbg("timeout3\r\n"); @@ -534,8 +536,11 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) set_ipl(ipl); - hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv); + hz = US_TO_TIMER(1000000.0) / (double)(start_tv - stop_tv); dbg("hz %d\r\n", (int32_t) hz); + OUTREG(CRTC_H_TOTAL_DISP, 640 / 8 - 1); + OUTREG(CRTC_V_TOTAL_DISP, 480 - 1); + dbg("h_total=%d vtotal=%d\r\n", INREG(CRTC_H_TOTAL_DISP), INREG(CRTC_V_TOTAL_DISP)); hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1); @@ -1260,7 +1265,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg { int i; - dbg("radeonfb: radeon_write_pll_regs\r\n"); + dbg("\r\n"); radeon_wait_for_fifo(rinfo, 20); #if 0 @@ -1367,16 +1372,15 @@ static void radeon_timer_func(void) int chg; int disp; -#ifdef FIXME_LATER static int32_t start_timer; /* delayed LVDS panel power up/down */ if (rinfo->lvds_timer) { if (!start_timer) - start_timer = *_hz_200; + start_timer = get_timer(); - if (((*_hz_200 - start_timer) * 5) >= (int32_t)rinfo->lvds_timer) + if (((start_timer - get_timer())) >= (int32_t)rinfo->lvds_timer) { rinfo->lvds_timer = 0; radeon_engine_idle(); @@ -1385,7 +1389,6 @@ static void radeon_timer_func(void) } else start_timer = 0; -#endif /* FIXME_LATER */ if (rinfo->RenderCallback != NULL) rinfo->RenderCallback(rinfo); @@ -2367,7 +2370,7 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent) offscreen_init(info); /* Probe screen types */ - dbg("probe screen types, monitor_layout: 0x%x\r\n", monitor_layout); + dbg("probe screen types, monitor_layout: %s\r\n", monitor_layout); radeon_probe_screens(rinfo, monitor_layout, (int) ignore_edid); /* Build mode list, check out panel native model */ @@ -2393,6 +2396,8 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent) #else install_vbl_timer(radeon_timer_func, 0); #endif + radeon_timer_func(); + //rinfo->RageTheatreCrystal = rinfo->RageTheatreTunerPort=rinfo->RageTheatreCompositePort = rinfo->RageTheatreSVideoPort = -1; //rinfo->tunerType = -1; return 0; diff --git a/BaS_gcc/radeon/radeon_i2c.c b/BaS_gcc/radeon/radeon_i2c.c index c049ea6..680439d 100644 --- a/BaS_gcc/radeon/radeon_i2c.c +++ b/BaS_gcc/radeon/radeon_i2c.c @@ -1,25 +1,30 @@ +#include "video.h" #include "radeonfb.h" -// #include "relocate.h" #include "edid.h" +#include "i2c.h" #include "driver_mem.h" +#define DEBUG +#include "debug.h" + + +#define CONFIG_FB_RADEON_I2C #ifdef CONFIG_FB_RADEON_I2C #define RADEON_DDC 0x50 -extern void mdelay(long msec); -extern void udelay(long usec); - static void radeon_gpio_setscl(void* data, int state) { struct radeon_i2c_chan *chan = data; struct radeonfb_info *rinfo = chan->rinfo; unsigned long val; + val = INREG(chan->ddc_reg) & ~(VGA_DDC_CLK_OUT_EN); - if(!state) + + if (!state) val |= VGA_DDC_CLK_OUT_EN; OUTREG(chan->ddc_reg, val); - (void)INREG(chan->ddc_reg); + (void) INREG(chan->ddc_reg); } static void radeon_gpio_setsda(void* data, int state) @@ -27,11 +32,12 @@ static void radeon_gpio_setsda(void* data, int state) struct radeon_i2c_chan *chan = data; struct radeonfb_info *rinfo = chan->rinfo; unsigned long val; + val = INREG(chan->ddc_reg) & ~(VGA_DDC_DATA_OUT_EN); - if(!state) + if (!state) val |= VGA_DDC_DATA_OUT_EN; OUTREG(chan->ddc_reg, val); - (void)INREG(chan->ddc_reg); + (void) INREG(chan->ddc_reg); } static int radeon_gpio_getscl(void* data) @@ -39,8 +45,9 @@ static int radeon_gpio_getscl(void* data) struct radeon_i2c_chan *chan = data; struct radeonfb_info *rinfo = chan->rinfo; unsigned long val; + val = INREG(chan->ddc_reg); - return(val & VGA_DDC_CLK_INPUT) ? 1 : 0; + return (val & VGA_DDC_CLK_INPUT) ? 1 : 0; } static int radeon_gpio_getsda(void* data) @@ -129,8 +136,10 @@ static unsigned char *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan) return NULL; msgs[1].buf = buf; - if(i2c_transfer(&chan->adapter, msgs, 2) == 2) + if (i2c_transfer(&chan->adapter, msgs, 2) == 2) return buf; + else + err("i2c_transfer() failed\r\n"); driver_mem_free(buf); return NULL; @@ -138,14 +147,14 @@ static unsigned char *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan) int32_t radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int32_t conn, uint8_t **out_edid) { - unsigned long reg = rinfo->i2c[conn-1].ddc_reg; + unsigned long reg = rinfo->i2c[conn - 1].ddc_reg; unsigned char *edid = NULL; int i, j; - // DPRINTVAL("radeonfb: radeon_probe_i2c_connector ", conn); - // DPRINT("\r\n"); + OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); + (void) INREG(reg); + for(i = 0; i < 3; i++) { /* For some old monitors we need the @@ -153,56 +162,68 @@ int32_t radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int32_t conn, ui */ OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); (void)INREG(reg); - mdelay(13); + wait_ms(13); + OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); (void)INREG(reg); + for(j = 0; j < 5; j++) { - mdelay(10); - if(INREG(reg) & VGA_DDC_CLK_INPUT) + wait_ms(10); + if (INREG(reg) & VGA_DDC_CLK_INPUT) break; } - if(j == 5) + + if (j == 5) continue; + OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN); - (void)INREG(reg); - mdelay(15); + (void) INREG(reg); + wait_ms(15); + OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN); - (void)INREG(reg); - mdelay(15); + (void) INREG(reg); + wait_ms(15); + OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - mdelay(15); + (void) INREG(reg); + wait_ms(15); + /* Do the real work */ - edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]); + edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn - 1]); OUTREG(reg, INREG(reg) | (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - mdelay(15); + (void) INREG(reg); + wait_ms(15); OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); + (void) INREG(reg); for(j = 0; j < 10; j++) { - mdelay(10); - if(INREG(reg) & VGA_DDC_CLK_INPUT) + wait_ms(10); + if (INREG(reg) & VGA_DDC_CLK_INPUT) break; } OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - mdelay(15); + (void) INREG(reg); + wait_ms(15); + OUTREG(reg, INREG(reg) | (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); - (void)INREG(reg); - if(edid) + (void) INREG(reg); + + if (edid) break; } /* Release the DDC lines when done or the Apple Cinema HD display * will switch off */ OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN)); - (void)INREG(reg); - if(out_edid) + (void) INREG(reg); + + if (out_edid) *out_edid = edid; - if(!edid) + + if (!edid) return MT_NONE; - if(edid[0x14] & 0x80) + + if (edid[0x14] & 0x80) { /* Fix detection using BIOS tables */ if(rinfo->is_mobility /*&& conn == ddc_dvi*/ && (INREG(LVDS_GEN_CNTL) & LVDS_ON)) diff --git a/BaS_gcc/radeon/radeon_monitor.c b/BaS_gcc/radeon/radeon_monitor.c index 8063098..579c8d2 100644 --- a/BaS_gcc/radeon/radeon_monitor.c +++ b/BaS_gcc/radeon/radeon_monitor.c @@ -4,8 +4,9 @@ #include "driver_mem.h" #include "bas_printf.h" #include "bas_string.h" +#include "video.h" -// #define DEBUG +#define DEBUG #include "debug.h" #ifndef INT_MAX @@ -171,33 +172,35 @@ static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo, const char * s2[0] = '\0'; } - if (strcmp(s1, "CRT")) + dbg("s1=%s, s2=%s \r\n", s1, s2); + + if (!strcmp(s1, "CRT")) { rinfo->mon1_type = MT_CRT; dbg("monitor 1 set to CRT\r\n"); } - else if (strcmp(s1, "TMDS")) + else if (!strcmp(s1, "TMDS")) { rinfo->mon1_type = MT_DFP; dbg("monitor 1 set to TMDS\r\n"); } - else if (strcmp(s1, "LVDS")) + else if (!strcmp(s1, "LVDS")) { rinfo->mon1_type = MT_LCD; dbg("monitor 1 set to LVDS\r\n"); } - if (strcmp(s2, "CRT")) + if (!strcmp(s2, "CRT")) { rinfo->mon2_type = MT_CRT; dbg("monitor 2 set to CRT\r\n"); } - else if (strcmp(s2, "TMDS")) + else if (!strcmp(s2, "TMDS")) { rinfo->mon2_type = MT_DFP; dbg("monitor 2 set to TMDS\r\n"); } - else if (strcmp(s2, "LVDS")) + else if (!strcmp(s2, "LVDS")) { rinfo->mon2_type = MT_LCD; dbg("monitor 2 set to LVDS\r\n"); @@ -211,9 +214,12 @@ static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo, const char * */ void radeon_probe_screens(struct radeonfb_info *rinfo, const char *monitor_layout, int ignore_edid) { + #ifdef CONFIG_FB_RADEON_I2C int ddc_crt2_used = 0; #endif + + dbg("monitor_layout=%s\r\n", monitor_layout); if (radeon_parse_monitor_layout(rinfo, monitor_layout)) { /* diff --git a/BaS_gcc/sys/BaS.c b/BaS_gcc/sys/BaS.c index d532bab..0959aa9 100644 --- a/BaS_gcc/sys/BaS.c +++ b/BaS_gcc/sys/BaS.c @@ -393,8 +393,8 @@ struct rom_header * Beware: Newer compilers refuse to dereference pointers to NULL and abort if the following * attribute isn't set. */ -static inline void fix_stram_header() __attribute__((optimize("no-delete-null-pointer-checks"))); -static inline void fix_stram_header() +static void fix_stram_header() __attribute__((optimize("no-delete-null-pointer-checks"))); +static void fix_stram_header() { struct rom_header *bas_header = (struct rom_header *) TARGET_ADDRESS; struct rom_header *stram_header = (struct rom_header *) 0x0; diff --git a/BaS_gcc/util/wait.c b/BaS_gcc/util/wait.c index 621aa2f..e655251 100644 --- a/BaS_gcc/util/wait.c +++ b/BaS_gcc/util/wait.c @@ -33,6 +33,21 @@ uint32_t get_timer(void) { return MCF_SLT_SCNT(0); } + +static uint32_t timer_value; + +void start_timeout(void) +{ + timer_value = get_timer(); +} + +bool end_timeout(uint32_t msec) +{ + msec *= SYSCLK; + + return (get_timer() - timer_value) < msec ? false : true; +} + /* * wait for the specified number of us on slice timer 0. Replaces the original routines that had * the number of useconds to wait for hardcoded in their name. diff --git a/BaS_gcc/video/fbmon.c b/BaS_gcc/video/fbmon.c index b15e767..9eb35e9 100644 --- a/BaS_gcc/video/fbmon.c +++ b/BaS_gcc/video/fbmon.c @@ -31,6 +31,9 @@ #include "fb.h" #include "edid.h" +#define DEBUG +#include "debug.h" + /* * EDID parser */ @@ -38,7 +41,6 @@ #define FBMON_FIX_HEADER 1 #define FBMON_FIX_INPUT 2 -#ifdef CONFIG_FB_MODE_HELPERS struct broken_edid { unsigned char manufacturer[4]; unsigned long model; @@ -148,7 +150,7 @@ static int edid_checksum(unsigned char *edid) /* checksum passed, everything's good */ err = 1; if(!err) - DPRINT("edid bad checksum\r\n"); + dbg("edid bad checksum\r\n"); return err; } @@ -163,7 +165,7 @@ static int edid_check_header(unsigned char *edid) err = 0; } if(!err) - DPRINT("edid bad header\r\n"); + dbg("edid bad header\r\n"); return err; } @@ -177,13 +179,11 @@ static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs) specs->serial = block[4] + (block[5] << 8) + (block[6] << 16) + (block[7] << 24); specs->year = block[9] + 1990; specs->week = block[8]; - DPRINT(" Manufacturer: "); - DPRINT((void *)specs->manufacturer); - DPRINTVAL("\r\n Model: ",specs->model); - DPRINTVAL("\r\n Serial#: ",specs->serial); - DPRINTVAL("\r\n Year: ",specs->year); - DPRINTVAL(" Week ",specs->week); - DPRINT("\r\n"); + dbg(" Manufacturer: %s\r\n", specs->manufacturer); + dbg(" Model: %s\r\n", specs->model); + dbg(" Serial#: %d\r\n", specs->serial); + dbg(" Year: %d\r\n", specs->year); + dbg(" Week %d\r\n", specs->week); } static void get_dpms_capabilities(unsigned char flags, struct fb_monspecs *specs) @@ -195,60 +195,63 @@ static void get_dpms_capabilities(unsigned char flags, struct fb_monspecs *specs specs->dpms |= FB_DPMS_SUSPEND; if(flags & DPMS_STANDBY) specs->dpms |= FB_DPMS_STANDBY; - DPRINT(" DPMS: Active "); - DPRINT((flags & DPMS_ACTIVE_OFF) ? "yes" : "no"); - DPRINT(", Suspend "); - DPRINT((flags & DPMS_SUSPEND) ? "yes" : "no"); - DPRINT(", Standby "); - DPRINT((flags & DPMS_STANDBY) ? "yes\r\n" : "no\r\n"); + dbg(" DPMS: Active %s\r\n", (flags & DPMS_ACTIVE_OFF) ? "yes" : "no"); + dbg(" Suspend: %s\r\n", (flags & DPMS_SUSPEND) ? "yes" : "no"); + dbg(" Standby %s\r\n", (flags & DPMS_STANDBY) ? "yes\r\n" : "no\r\n"); } static void get_chroma(unsigned char *block, struct fb_monspecs *specs) { int tmp; - DPRINT(" Chroma\r\n"); + /* Chromaticity data */ tmp = ((block[5] & (3 << 6)) >> 6) | (block[0x7] << 2); tmp *= 1000; tmp += 512; specs->chroma.redx = tmp/1024; - DPRINTVAL(" RedX: ",specs->chroma.redx/10); + + dbg(" Chroma\r\n"); + dbg(" RedX: %d\r\n", specs->chroma.redx / 10); tmp = ((block[5] & (3 << 4)) >> 4) | (block[0x8] << 2); tmp *= 1000; tmp += 512; specs->chroma.redy = tmp/1024; - DPRINTVAL("% RedY: ",specs->chroma.redy/10); + + dbg(" RedY: %d\r\n", specs->chroma.redy / 10); tmp = ((block[5] & (3 << 2)) >> 2) | (block[0x9] << 2); tmp *= 1000; tmp += 512; specs->chroma.greenx = tmp/1024; - DPRINTVAL("%\r\n GreenX: ",specs->chroma.greenx/10); + + dbg(" GreenX: %d\r\n", specs->chroma.greenx / 10); + tmp = (block[5] & 3) | (block[0xa] << 2); tmp *= 1000; tmp += 512; - specs->chroma.greeny = tmp/1024; - DPRINTVAL("% GreenY: ",specs->chroma.greeny/10); + specs->chroma.greeny = tmp / 1024; + dbg(" GreenY: %d\r\n", specs->chroma.greeny / 10); tmp = ((block[6] & (3 << 6)) >> 6) | (block[0xb] << 2); tmp *= 1000; tmp += 512; specs->chroma.bluex = tmp/1024; - DPRINTVAL("%\r\n BlueX: ",specs->chroma.bluex/10); + dbg(" BlueX: %d\r\n", specs->chroma.bluex / 10); tmp = ((block[6] & (3 << 4)) >> 4) | (block[0xc] << 2); tmp *= 1000; tmp += 512; specs->chroma.bluey = tmp/1024; - DPRINTVAL("% BlueY: ",specs->chroma.bluey/10); + + dbg(" BlueY: %d\r\n", specs->chroma.bluey / 10); tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); tmp *= 1000; tmp += 512; specs->chroma.whitex = tmp/1024; - DPRINTVAL("%\r\n WhiteX: ",specs->chroma.whitex/10); + dbg(" WhiteX: %d\r\n", specs->chroma.whitex / 10); + tmp = (block[6] & 3) | (block[0xe] << 2); tmp *= 1000; tmp += 512; specs->chroma.whitey = tmp/1024; - DPRINTVAL("% WhiteY: ",specs->chroma.whitey/10); - DPRINT("%\r\n"); + dbg(" WhiteY: %d\r\n", specs->chroma.whitey / 10); } static int edid_is_serial_block(unsigned char *block) @@ -317,95 +320,95 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) { calc_mode_timings(720, 400, 70, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; - DPRINT(" 720x400@70Hz\r\n"); + dbg(" 720x400@70Hz\r\n"); } if(c&0x40) { calc_mode_timings(720, 400, 88, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; - DPRINT(" 720x400@88Hz\r\n"); + dbg(" 720x400@88Hz\r\n"); } if(c&0x20) { mode[num++] = vesa_modes[3]; - DPRINT(" 640x480@60Hz\r\n"); + dbg(" 640x480@60Hz\r\n"); } if(c&0x10) { calc_mode_timings(640, 480, 67, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; - DPRINT(" 640x480@67Hz\r\n"); + dbg(" 640x480@67Hz\r\n"); } if(c&0x08) { mode[num++] = vesa_modes[4]; - DPRINT(" 640x480@72Hz\r\n"); + dbg(" 640x480@72Hz\r\n"); } if(c&0x04) { mode[num++] = vesa_modes[5]; - DPRINT(" 640x480@75Hz\r\n"); + dbg(" 640x480@75Hz\r\n"); } if(c&0x02) { mode[num++] = vesa_modes[7]; - DPRINT(" 800x600@56Hz\r\n"); + dbg(" 800x600@56Hz\r\n"); } if(c&0x01) { mode[num++] = vesa_modes[8]; - DPRINT(" 800x600@60Hz\r\n"); + dbg(" 800x600@60Hz\r\n"); } c = block[1]; if(c&0x80) { mode[num++] = vesa_modes[9]; - DPRINT(" 800x600@72Hz\r\n"); + dbg(" 800x600@72Hz\r\n"); } if(c&0x40) { mode[num++] = vesa_modes[10]; - DPRINT(" 800x600@75Hz\r\n"); + dbg(" 800x600@75Hz\r\n"); } if(c&0x20) { calc_mode_timings(832, 624, 75, &mode[num]); mode[num++].flag = FB_MODE_IS_CALCULATED; - DPRINT(" 832x624@75Hz\r\n"); + dbg(" 832x624@75Hz\r\n"); } if(c&0x10) { mode[num++] = vesa_modes[12]; - DPRINT(" 1024x768@87Hz Interlaced\r\n"); + dbg(" 1024x768@87Hz Interlaced\r\n"); } if(c&0x08) { mode[num++] = vesa_modes[13]; - DPRINT(" 1024x768@60Hz\r\n"); + dbg(" 1024x768@60Hz\r\n"); } if(c&0x04) { mode[num++] = vesa_modes[14]; - DPRINT(" 1024x768@70Hz\r\n"); + dbg(" 1024x768@70Hz\r\n"); } if(c&0x02) { mode[num++] = vesa_modes[15]; - DPRINT(" 1024x768@75Hz\r\n"); + dbg(" 1024x768@75Hz\r\n"); } if(c&0x01) { mode[num++] = vesa_modes[21]; - DPRINT(" 1280x1024@75Hz\r\n"); + dbg(" 1280x1024@75Hz\r\n"); } c = block[2]; if(c&0x80) { mode[num++] = vesa_modes[17]; - DPRINT(" 1152x870@75Hz\r\n"); + dbg(" 1152x870@75Hz\r\n"); } - DPRINTVAL(" Manufacturer's mask: ",c&0x7F); - DPRINT("\r\n"); + dbg(" Manufacturer's mask: 0x%02x\r\n", c & 0x7F); + return num; } @@ -424,10 +427,8 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode) case 3: yres = (xres * 9)/16; break; } refresh = (block[1] & 0x3f) + 60; - DPRINTVAL(" ",xres); - DPRINTVAL("x",yres); - DPRINTVAL("@",refresh); - DPRINT("Hz\r\n"); + dbg("%dx%d@ Hz\r\n",xres, yres, refresh); + for(i = 0; i < VESA_MODEDB_SIZE; i++) { if(vesa_modes[i].xres == xres && vesa_modes[i].yres == yres @@ -470,19 +471,19 @@ static void get_detailed_timing(unsigned char *block, struct fb_videomode *mode) mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) * (V_ACTIVE + V_BLANKING)); mode->vmode = 0; mode->flag = FB_MODE_IS_DETAILED; - DPRINTVAL(" ",PIXEL_CLOCK/1000000); - DPRINTVAL(" MHz ",H_ACTIVE); - DPRINTVAL(" ",H_ACTIVE + H_SYNC_OFFSET); - DPRINTVAL(" ",H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); - DPRINTVAL(" ",H_ACTIVE + H_BLANKING); - DPRINTVAL(" ",V_ACTIVE); - DPRINTVAL(" ",V_ACTIVE + V_SYNC_OFFSET); - DPRINTVAL(" ",V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH); - DPRINTVAL(" ",V_ACTIVE + V_BLANKING); - DPRINT((HSYNC_POSITIVE) ? " +" : " -"); - DPRINT("HSync "); - DPRINT((VSYNC_POSITIVE) ? "+" : "-"); - DPRINT("VSync\r\n"); + dbg("%d MHz 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\r\n", + PIXEL_CLOCK / 1000000, + H_ACTIVE, + H_ACTIVE + H_SYNC_OFFSET, + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, + H_ACTIVE + H_BLANKING, + V_ACTIVE, + V_ACTIVE + V_SYNC_OFFSET, + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, + V_ACTIVE + V_BLANKING); + dbg("Hsync %s Vsync %s\r\n", + (HSYNC_POSITIVE) ? " +" : " -", + (VSYNC_POSITIVE) ? "+" : "-"); } #define MAX_DB_ALLOC 100 @@ -566,14 +567,14 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) return NULL; } *dbsize = 0; - DPRINT(" Supported VESA Modes\r\n"); + dbg(" Supported VESA Modes\r\n"); block = edid + ESTABLISHED_TIMING_1; num += get_est_timing(block, &mode[num]); - DPRINT(" Standard Timings\r\n"); + dbg(" Standard Timings\r\n"); block = edid + STD_TIMING_DESCRIPTIONS_START; for(i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) num += get_std_timing(block, &mode[num]); - DPRINT(" Detailed Timings\r\n"); + dbg(" Detailed Timings\r\n"); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for(i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { @@ -615,10 +616,10 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) int i, retval = 1; unsigned char *block; block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - DPRINT(" Monitor Operating Limits: "); + dbg(" Monitor Operating Limits: "); for(i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if(edid_is_limits_block(block)) + if (edid_is_limits_block(block)) { specs->hfmin = H_MIN_RATE * 1000; specs->hfmax = H_MAX_RATE * 1000; @@ -627,7 +628,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) specs->dclkmax = MAX_PIXEL_CLOCK * 1000000; specs->gtf = (GTF_SUPPORT) ? 1 : 0; retval = 0; - DPRINT("From EDID\r\n"); + dbg("From EDID\r\n"); break; } } @@ -639,7 +640,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) modes = fb_create_modedb(edid, &num_modes); if(!modes) { - DPRINT("None Available\r\n"); + dbg("None Available\r\n"); return 1; } retval = 0; @@ -661,15 +662,15 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) if(specs->vfmin == 0 || specs->vfmin > hz) specs->vfmin = hz; } - DPRINT("Extrapolated\r\n"); + dbg("Extrapolated\r\n"); fb_destroy_modedb(modes); } - DPRINTVAL(" H: ",specs->hfmin/1000); - DPRINTVAL("-",specs->hfmax/1000); - DPRINTVAL("KHz V: ",specs->vfmin); - DPRINTVAL("-",specs->vfmax); - DPRINTVAL("Hz DCLK: ",specs->dclkmax/1000000); - DPRINT("MHz\r\n"); + dbg(" H: %d - %d kHz V: %d - %d kHz, DCLK: %d MHz\r\n", + specs->hfmin / 1000, + specs->hfmax / 1000, + specs->vfmin, + specs->vfmax, + specs->dclkmax / 1000000); return retval; } @@ -683,108 +684,87 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) if(c) { specs->input |= FB_DISP_DDI; - DPRINT(" Digital Display Input"); + dbg(" Digital Display Input"); } else { - DPRINT(" Analog Display Input: Input Voltage - "); switch ((block[0] & 0x60) >> 5) { case 0: - DPRINT("0.700V/0.300V"); + //dbg(" Analog Display Input: Input Voltage - 0.700V/0.300V"); specs->input |= FB_DISP_ANA_700_300; break; case 1: - DPRINT("0.714V/0.286V"); + //dbg("0.714V/0.286V"); specs->input |= FB_DISP_ANA_714_286; break; case 2: - DPRINT("1.000V/0.400V"); + //dbg("1.000V/0.400V"); specs->input |= FB_DISP_ANA_1000_400; break; case 3: - DPRINT("0.700V/0.000V"); + //dbg("0.700V/0.000V"); specs->input |= FB_DISP_ANA_700_000; break; } } - DPRINT("\r\n Sync: "); + // dbg("Sync: "); c = block[0] & 0x10; if(c) { - DPRINT(" Configurable signal level\r\n"); + dbg(" Configurable signal level\r\n"); } c = block[0] & 0x0f; specs->signal = 0; if(c & 0x10) { - DPRINT("Blank to Blank "); + //DPRINT("Blank to Blank "); specs->signal |= FB_SIGNAL_BLANK_BLANK; } if(c & 0x08) { - DPRINT("Separate "); + //DPRINT("Separate "); specs->signal |= FB_SIGNAL_SEPARATE; } if(c & 0x04) { - DPRINT("Composite "); + //DPRINT("Composite "); specs->signal |= FB_SIGNAL_COMPOSITE; } if(c & 0x02) { - DPRINT("Sync on Green "); + //DPRINT("Sync on Green "); specs->signal |= FB_SIGNAL_SYNC_ON_GREEN; } if(c & 0x01) { - DPRINT("Serration on "); + // DPRINT("Serration on "); specs->signal |= FB_SIGNAL_SERRATION_ON; } - DPRINT("\r\n"); specs->max_x = block[1]; specs->max_y = block[2]; - DPRINT(" Max H-size in cm: "); - if(specs->max_x) - { - DPRINTVAL("",specs->max_x); - DPRINT("\r\n"); - } - else - { - DPRINT("variable\r\n"); - } - DPRINT(" Max V-size in cm: "); - if(specs->max_y) - { - DPRINTVAL("",specs->max_y); - DPRINT("\r\n"); - } - else - { - DPRINT("variable\r\n"); - } + c = block[3]; + specs->gamma = c+100; - DPRINTVAL(" Gamma: ",specs->gamma/100); - DPRINT("\r\n"); + dbg(" Gamma %d\r\n: ",specs->gamma / 100); get_dpms_capabilities(block[4], specs); switch ((block[4] & 0x18) >> 3) { case 0: - DPRINT(" Monochrome/Grayscale\r\n"); + //DPRINT(" Monochrome/Grayscale\r\n"); specs->input |= FB_DISP_MONO; break; case 1: - DPRINT(" RGB Color Display\r\n"); + //DPRINT(" RGB Color Display\r\n"); specs->input |= FB_DISP_RGB; break; case 2: - DPRINT(" Non-RGB Multicolor Display\r\n"); + //DPRINT(" Non-RGB Multicolor Display\r\n"); specs->input |= FB_DISP_MULTI; break; default: - DPRINT(" Unknown\r\n"); + //DPRINT(" Unknown\r\n"); specs->input |= FB_DISP_UNKNOWN; break; } @@ -793,17 +773,17 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) c = block[4] & 0x7; if(c & 0x04) { - DPRINT(" Default color format is primary\r\n"); + dbg(" Default color format is primary\r\n"); specs->misc |= FB_MISC_PRIM_COLOR; } if(c & 0x02) { - DPRINT(" First DETAILED Timing is preferred\r\n"); + dbg(" First DETAILED Timing is preferred\r\n"); specs->misc |= FB_MISC_1ST_DETAIL; } if(c & 0x01) { - DPRINT(" Display is GTF capable\r\n"); + dbg(" Display is GTF capable\r\n"); specs->gtf = 1; } } @@ -851,7 +831,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) return 0; } } - DPRINT("edid no timing block\r\n"); + dbg("edid no timing block\r\n"); return 1; } @@ -870,12 +850,11 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) memset((char *)specs, 0, sizeof(struct fb_monspecs)); specs->version = edid[EDID_STRUCT_VERSION]; specs->revision = edid[EDID_STRUCT_REVISION]; - DPRINT("========================================\r\n"); - DPRINT("Display Information (EDID)\r\n"); - DPRINT("========================================\r\n"); - DPRINTVAL(" EDID Version ",specs->version); - DPRINTVAL(".",specs->revision); - DPRINT("\r\n"); + dbg("========================================\r\n"); + dbg("Display Information (EDID)\r\n"); + dbg("========================================\r\n"); + dbg(" EDID Version %d.%d\r\n", specs->version, specs->revision); + parse_vendor_block(edid + ID_MANUFACTURER_NAME, specs); block = edid + DETAILED_TIMING_DESCRIPTIONS_START; for(i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) @@ -883,29 +862,29 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) if(edid_is_serial_block(block)) { copy_string(block, specs->serial_no); - DPRINT(" Serial Number: "); - DPRINT((void *)specs->serial_no); - DPRINT("\r\n"); + //DPRINT(" Serial Number: "); + //DPRINT((void *)specs->serial_no); + //DPRINT("\r\n"); } else if(edid_is_ascii_block(block)) { copy_string(block, specs->ascii); - DPRINT(" ASCII Block: "); - DPRINT((void *)specs->ascii); - DPRINT("\r\n"); + //DPRINT(" ASCII Block: "); + //DPRINT((void *)specs->ascii); + //DPRINT("\r\n"); } else if(edid_is_monitor_block(block)) { copy_string(block, specs->monitor); - DPRINT(" Monitor Name: "); - DPRINT((void *)specs->monitor); - DPRINT("\r\n"); + //DPRINT(" Monitor Name: "); + //DPRINT((void *)specs->monitor); + //DPRINT("\r\n"); } } - DPRINT(" Display Characteristics:\r\n"); + //DPRINT(" Display Characteristics:\r\n"); get_monspecs(edid, specs); specs->modedb = fb_create_modedb(edid, (int *)&specs->modedb_len); - DPRINT("========================================\r\n"); + dbg("========================================\r\n"); } /* @@ -1225,29 +1204,6 @@ int fb_get_mode(int flags, unsigned long val, struct fb_var_screeninfo *var, str return 0; } -#else - -int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) -{ - return 1; -} - -void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) -{ - specs = NULL; -} - -void fb_destroy_modedb(struct fb_videomode *modedb) -{ -} - -int fb_get_mode(int flags, unsigned long val, struct fb_var_screeninfo *var, struct fb_info *info) -{ - return -1; // -EINVAL; -} - -#endif /* CONFIG_FB_MODE_HELPERS */ - /* * fb_validate_mode - validates var against monitor capabilities * @var: pointer to fb_var_screeninfo diff --git a/BaS_gcc/video/video.c b/BaS_gcc/video/video.c index a1068fa..676b76e 100644 --- a/BaS_gcc/video/video.c +++ b/BaS_gcc/video/video.c @@ -272,7 +272,14 @@ void videl_screen_init(void) #endif /* _USE_VIDEL_ */ -static struct radeonfb_info rfb; +static uint8_t mon1_EDID[40]; +static uint8_t mon2_EDID[40]; + +static struct radeonfb_info rfb = +{ + .mon1_EDID = mon1_EDID, + .mon2_EDID = mon2_EDID, +}; static struct fb_var_screeninfo default_fb = { @@ -293,7 +300,7 @@ static struct fb_var_screeninfo default_fb = .height = 1024, .width = 1280, .accel_flags = 0L, - .pixclock = 70 * 100000000L, + .pixclock = 70 * 10000000L, .left_margin = 0, .right_margin = 0, .upper_margin = 0, @@ -330,7 +337,7 @@ static struct fb_info fb = struct fb_info *info_fb = &fb; -const char monitor_layout[1024] = "CRT,CRT"; +const char monitor_layout[1024] = "\0"; int16_t ignore_edid; struct mode_option resolution = @@ -340,7 +347,7 @@ struct mode_option resolution = .height = 1024, .bpp = 8, .freq = 60, - .flags = MODE_VESA_FLAG + .flags = 0 }; int16_t force_measure_pll; @@ -413,7 +420,7 @@ void video_init(void) } index++; } while (handle > 0); - xprintf("%s: RADEON video card %sfound and %sregistered\r\n", __FUNCTION__, + inf("RADEON video card %sfound and %sregistered\r\n", (radeon_found ? "" : "not "), (radeon_found ? "" : "not ")); } diff --git a/BaS_gcc/x86emu/x86biosemu.c b/BaS_gcc/x86emu/x86biosemu.c index d2168da..5a6e9a3 100644 --- a/BaS_gcc/x86emu/x86biosemu.c +++ b/BaS_gcc/x86emu/x86biosemu.c @@ -10,7 +10,7 @@ #include "pci_ids.h" #include "x86pcibios.h" -// #define DEBUG +#define DEBUG #include "debug.h" #define USE_SDRAM @@ -112,6 +112,9 @@ static uint16_t inw(struct X86EMU *emu, uint16_t port) return val; } +#define PC_PCI_INDEX_PORT 0xcf8 +#define PC_PCI_DATA_PORT 0xcfc + static uint32_t inl(struct X86EMU *emu, uint16_t port) { uint32_t val = 0; @@ -120,13 +123,12 @@ static uint32_t inl(struct X86EMU *emu, uint16_t port) { val = swpl(*(uint32_t *)(offset_io + (uint32_t) port)); } - else if (port == 0xCF8) + else if (port == PC_PCI_INDEX_PORT) { val = config_address_reg; } - else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) != 0)) + else if ((port == PC_PCI_DATA_PORT) && ((config_address_reg & 0x80000000) != 0)) { - dbg("PCI BIOS access to register %x\r\n", config_address_reg); switch (config_address_reg & 0xFC) { case PCIIDR: @@ -141,7 +143,7 @@ static uint32_t inl(struct X86EMU *emu, uint16_t port) val = pci_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC); break; } - dbg("inl(0x%x) = 0x%x\r\n", port, val); + // dbg("PCI inl from register %x, value = 0x%08x\r\n", config_address_reg, val); } return val; @@ -169,19 +171,19 @@ static void outl(struct X86EMU *emu, uint16_t port, uint32_t val) { *(uint32_t *)(offset_io + (uint32_t) port) = swpl(val); } - else if (port == 0xCF8) + else if (port == PC_PCI_INDEX_PORT) { config_address_reg = val; } - else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) !=0)) + else if ((port == PC_PCI_DATA_PORT) && ((config_address_reg & 0x80000000) !=0)) { + dbg("outl(0x%x, 0x%x) to PCI config space\r\n", port, val); if ((config_address_reg & 0xFC) == PCIBAR1) { offset_port = (uint16_t) val & 0xFFFC; } else { - dbg("outl(0x%x, 0x%x) to PCI config space\r\n", port, val); pci_write_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC, val); } } @@ -195,7 +197,6 @@ static void do_int(struct X86EMU *emu, int num) switch (num) { -#ifndef _PC case 0x10: /* video interrupt */ /* fall through intentional */ @@ -207,7 +208,23 @@ static void do_int(struct X86EMU *emu, int num) case 0x6d: /* VGA internal interrupt */ - dbg("int %02xh, AH=0x%02x, AL=0x%02x\r\n", num, emu->x86.register_a.I8_reg.h_reg, emu->x86.register_a.I8_reg.l_reg); + dbg("int %02xh, AH=0x%02x, AL=0x%02x\r\n", num, + emu->x86.register_a.I8_reg.h_reg, + emu->x86.register_a.I8_reg.l_reg); + + if (emu->x86.register_a.I8_reg.h_reg == 0x13) /* VGA write string */ + { + int num_chars = emu->x86.register_c.I16_reg.x_reg; + int seg = emu->x86.register_es; + int off = emu->x86.register_bp.I16_reg.x_reg; + int str = (seg << 4) + off; + int i; + + dbg("string to output at 0x%04x:0x%04x length=0x%04x\r\n", seg, off, num_chars); + + for (i = 0; i < num_chars; i++) + xprintf("%c", * (char *)(0x0100000 + str + i)); + } if (getIntVect(emu, num) == 0x0000) err("uninitialised int vector\r\n"); @@ -218,7 +235,7 @@ static void do_int(struct X86EMU *emu, int num) ret = 1; } break; -#endif + case 0x15: //ret = int15_handler(); ret = 1; diff --git a/BaS_gcc/x86emu/x86pcibios.c b/BaS_gcc/x86emu/x86pcibios.c index f3e556f..1c34eec 100644 --- a/BaS_gcc/x86emu/x86pcibios.c +++ b/BaS_gcc/x86emu/x86pcibios.c @@ -4,9 +4,10 @@ #include "x86pcibios.h" #include "x86emu_regs.h" #include "bas_printf.h" + extern unsigned short offset_port; -// #define DEBUG +#define DEBUG #include "debug.h" int x86_pcibios_handler(struct X86EMU *emu) @@ -77,7 +78,7 @@ int x86_pcibios_handler(struct X86EMU *emu) dbg("READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x\r\n", emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI); dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 7); emu->x86.R_CL = pci_read_config_byte(dev, emu->x86.R_DI); - dbg("value = %x\r\n", emu->x86.R_CL); + dbg("dev=0x%04x value = 0x%04x\r\n", emu->x86.R_CL); emu->x86.R_AH = SUCCESSFUL; emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */ ret = 1; @@ -91,7 +92,7 @@ int x86_pcibios_handler(struct X86EMU *emu) emu->x86.R_CX = offset_port + 1; else emu->x86.R_CX = pci_read_config_word(dev, emu->x86.R_DI); - dbg("value = %x\r\n", emu->x86.R_CX); + dbg("offset_port=0x%04x dev=0x%04x, value = %x\r\n", offset_port, dev, emu->x86.R_CX); emu->x86.R_AH = SUCCESSFUL; emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */ ret = 1;