Uwe Hermann wrote:
> On Mon, Mar 26, 2007 at 02:10:20AM -0400, Corey Osgood wrote:
>> Alright, I know I ask too many questions, but what would cause uart_init
>> to hang? I'm trying to get serial output on ite it8705f, and my POST
>> card tells me that it's hanging during uart_init. I've made a bunch of
>> changes to it8705f_early_serial.c, mainly to set up serial port 1
>> manually, but nothing seems to help. Also, there's one small error in
>> the last line of that file, according to the datasheet:
>>
>>     it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CC, 0x02); //need to
>> change 0x02 to 0x01
> 
> This line is correct, I think. The datasheet says
> 
>   Set bit 1 of the Configure Control Register (Index: 02h) to "1" to exit
>   the MB PnP mode.
> 
> IT8705F_CONFIG_REG_CC is 0x02, and the 0x02 in the line above is correct
> because it sets bit 1 (not bit 0).
> 
> 
> I _think_ I got serial output with that Super I/O at some point, but I
> can't remember exactly, so maybe there's still something todo...
> 
> 
> Uwe.
> 

I've attached my it8705f_early_serial.c and auto.c. And yes, Uwe, you
were right, it was correct. I even put in a comment about it and still
read it wrong. But, I'm still not getting serial output, even with that
fixed. I've put in a few outb()s, and that tells me it's finishing with
the early serial, but not leaving uart_init(). I'm wondering if the
vt8235 is somehow interfering with the serial output. Suggestions?

Thanks,
Corey
#define ASSEMBLY 1

#include <stdint.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#if 0
#include <cpu/x86/lapic.h>
#endif
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <arch/hlt.h>
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "northbridge/via/vt8623/raminit.h"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"

/* sensors-detect found this at 0x0290??*/
#define SERIAL_DEV PNP_DEV(0x2e, IT8705F_SP1)

/*
 */
void udelay(int usecs) 
{
	int i;
	for(i = 0; i < usecs; i++)
		outb(i&0xff, 0x80);
}

#include "lib/delay.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "debug.c"

#include "southbridge/via/vt8235/vt8235_early_smbus.c"
#include "superio/ite/it8705f/it8705f_early_serial.c"
//#include "southbridge/via/vt8235/vt8235_early_serial.c"

static void memreset_setup(void)
{
}

static inline int spd_read_byte(unsigned device, unsigned address)
{
	unsigned char c;
	c = smbus_read_byte(device, address);
	return c;
}

#include "northbridge/via/vt8623/raminit.c"

static void enable_mainboard_devices(void) 
{
	
	device_t dev;
	/* This should work and save a few CPU cycles and pci read/writes
	 *  The southbridge should always be in the same location, so rely on it
	 * Then check the last 2 digits of the device id, there's a chance
	 * that this could fail, but a slim one (it would have to be a PCI card)
	 * If that doesn't match, find it the old way */
	
	/* Ack, it didn't work. Try again some other time */	
	
	/* Todo: test if this works or falls back */
	
	/* VT8235 PCI-ISA Bridge */
	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, 
					PCI_DEVICE_ID_VIA_8235), 0); 
	if(dev == PCI_DEV_INVALID) {
		outb(0x33, 0x80);
		die("Southbridge not found!\r\n");
	}
	pci_write_config8(dev, 0x50, 0x80);/* Disable modem */
	pci_write_config8(dev, 0x51, 0x1d);//lspci says 1d
	
	dev += 0x100;
	
	pci_write_config8(dev, 0x04, 0x07);/* Enable IDE */
	pci_write_config8(dev, 0x40, 0x03);/* Enable both channels */
	pci_write_config8(dev, 0x42, 0x00);/* Put the both channels into compatability mode */
	/* These two registers are read only!! */
	pci_write_config8(dev, 0x3c, 0x0e);/* IRQ14 (default) */
	pci_write_config8(dev, 0x3d, 0x00);/* Interrupt Routing Mode (?!) */
}

static void enable_shadow_ram(void) 
{
	device_t dev = 0; /* no need to look up 0:0.0 */
	unsigned char shadowreg;
	/* dev 0 for southbridge */
	shadowreg = pci_read_config8(dev, 0x63);
	/* 0xf0000-0xfffff */
	shadowreg |= 0x30;
	pci_write_config8(dev, 0x63, shadowreg);
}

static void main(unsigned long bist)
{
	outb(0x70, 0x80);
	unsigned long x;
	device_t dev;

	/*
	 * Enable VGA; 32MB buffer.
	 */
	//pci_write_config8(0, 0xe1, 0xdd);
	
	/* This mainboard has 2 SuperI/Os: the one built into the vt8235, and the ITE.
	   Some continuity tests tell me that the ITE is used */

	/* it8705f doesn't use these parameters, it sets its own
	   Send them anyways, but keep that in mind */
	//enable_vt8235_serial();
	outb(0x19,0x80);
	it8705f_enable_serial(SERIAL_DEV, TTYS0_BASE);
	uart_init();
	outb(0x22,0x80);
	console_init();
	outb(0x23,0x80);
	print_debug("Serial initialized\r\n");

	enable_smbus(); /* Perhaps this fucks up my serial config? */
	print_debug("SMBus Enabled\r\n");

	/* Halt if there was a built in self test failure */
	report_bist_failure(bist);

	// init_timer();

	outb(5, 0x80);	

	print_debug(" Enabling mainboard devices\r\n");
	enable_mainboard_devices();

	print_debug(" Enabling shadow ram\r\n");
	enable_shadow_ram();

	ddr_ram_setup((const struct mem_controller *)0);
	
#if 0
	static const struct {
		unsigned long lo, hi;
	} check_addrs[] = {
		/* Check 16MB of memory @ 0*/
		{ 0x00000000, 0x01000000 },
	};
	int i;
	for(i = 0; i < sizeof(check_addrs)/sizeof(check_addrs[0]); i++) {
		ram_check(check_addrs[i].lo, check_addrs[i].hi);
	}
#endif

	if (bist == 0) {
		print_debug(" Doing MTRR init.\r\n");
		early_mtrr_init();
	}

	//dump_pci_devices();
	
	print_spew("Leaving auto.c:main()\r\n");
}
/*
 * This file is part of the LinuxBIOS project.
 *
 * Copyright (C) 2006 Uwe Hermann <[EMAIL PROTECTED]>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <arch/romcc_io.h>
#include "it8705f.h"

/* The base address is 0x2e or 0x4e, depending on config bytes. */
#define SIO_BASE                     0x2e
#define SIO_INDEX                    SIO_BASE
#define SIO_DATA                     SIO_BASE+1

/* Global configuration registers. */
#define IT8705F_CONFIG_REG_CC        0x02 /* Configure Control (write-only). */
#define IT8705F_CONFIG_REG_LDN       0x07 /* Logical Device Number. */
#define IT8705F_CONFIG_REG_CONFIGSEL 0x22 /* Configuration Select. */

/* WTF? 0x23 and 0x24 are swapped here (when compared to other IT87xx). */
#define IT8705F_CONFIG_REG_CLOCKSEL  0x24 /* Clock Selection, Flash I/F. */
#define IT8705F_CONFIG_REG_SWSUSP    0x23 /* Software Suspend. */

#define IT8705F_CONFIGURATION_PORT   0x2e /* Write-only. */

/* The content of IT8705F_CONFIG_REG_LDN (index 0x07) must be set to the
   LDN the register belongs to, before you can access the register. */
static void it8705f_sio_write(uint8_t ldn, uint8_t index, uint8_t value)
{
	outb(IT8705F_CONFIG_REG_LDN, SIO_BASE);
	outb(ldn, SIO_DATA);
	outb(index, SIO_BASE);
	outb(value, SIO_DATA);
}

/* Enable the peripheral devices on the IT8705F Super I/O chip. */
static void it8705f_enable_serial(device_t dev, unsigned iobase)
{
	/* Hmm, lets dump a post code just to say this has started */
	outb(0x20, 0x80);

	/* (1) Enter the configuration state (MB PnP mode). */

	/* Perform MB PnP setup to put the SIO chip at 0x2e. */
	/* Base address 0x2e: 0x87 0x01 0x55 0x55. */
	/* Base address 0x4e: 0x87 0x01 0x55 0xaa. */
	outb(0x87, IT8705F_CONFIGURATION_PORT);
	outb(0x01, IT8705F_CONFIGURATION_PORT);
	outb(0x55, IT8705F_CONFIGURATION_PORT);
//#if SIO_BASE == 0x2e
	outb(0x55, IT8705F_CONFIGURATION_PORT);
//#else /* SIO_BASE == 0x4e */
	//outb(0xaa, IT8705F_CONFIGURATION_PORT);
//#endif
	/* (2) Modify the data of configuration registers. */

	/* Select the chip to configure (if there's more than one).
           Set bit 7 to select JP3=1, clear bit 7 to select JP3=0.
           If this register is not written, both chips are configured. */
	//it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CONFIGSEL, 0x40);

	/* Enable all devices. */
	/* Setup GPIO */
#if 0
	it8705f_sio_write(0x05,  0x25, 0x00);
	it8705f_sio_write(0x05,  0x26, 0x00);
	it8705f_sio_write(0x05,  0x27, 0x00);
	it8705f_sio_write(0x05,  0x28, 0xFF);//Use joystick for GPIO
	it8705f_sio_write(0x05,  0x29, 0x00);
	it8705f_sio_write(0x05,  0x2A, 0xF0);//Use IR for GPIO
#endif	

	/* TODO: make this more...modular
	   We dont want the kernel wasting time on devices we don't have/want */
	/* For now this should work. Leave it be */
	it8705f_sio_write(IT8705F_FDC,  0x30, 0x01); /* Floppy */
	it8705f_sio_write(IT8705F_SP1,  0x30, 0x01); /* Serial port 1 */
	it8705f_sio_write(IT8705F_SP1,  0x70, 0x04); /* Map COM1->IRQ4 */
	//it8705f_sio_write(IT8705F_SP1,  0x33, 0x03); /* This might work. set to 8N1 */
	
	it8705f_sio_write(IT8705F_SP2,  0x30, 0x01); /* Serial port 2 */
	it8705f_sio_write(IT8705F_SP2,  0x70, 0x03); /* Map COM2-> IRQ3 */
	it8705f_sio_write(IT8705F_SP2,  0xF2, 0x03); /* Can't remember, but it might help */
	it8705f_sio_write(IT8705F_PP,   0x30, 0x01); /* Parallel port */
	it8705f_sio_write(IT8705F_EC,   0x30, 0x01); /* Environment controller */
	it8705f_sio_write(IT8705F_GAME, 0x30, 0x00); /* GAME port */
	it8705f_sio_write(IT8705F_IR,   0x30, 0x00); /* Consumer IR */
	it8705f_sio_write(IT8705F_MIDI, 0x30, 0x00); /* MIDI port */

	/* Select 24MHz CLKIN (set bit 0->1). */
	/* How do we determine CLKIN? */
	it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CLOCKSEL, 0x01);

	/* Clear software suspend mode (clear bit 0). TODO: Needed? */
	/* Was commented, uncommented to possibly fix m789cg */
	it8705f_sio_write(0x00, IT8705F_CONFIG_REG_SWSUSP, 0x00);

	/* (3) Exit the configuration state (MB PnP mode). */
	/* Set bit 1 of the Configure Control Register (Index: 02h) to 1 */
	it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CC, 0x02);

	/* Serial output should be set up. Dump a post code to say so */
	outb(0x21,0x80);
}

-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to