/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2005 AMD
 * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

#include <reset.h>
#include "bcm5785.h"

static void bcm5785_enable_lpc(void)
{
        uint8_t byte;
        device_t dev;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);

        /* LPC Control 0 */
        byte = pci_read_config8(dev, 0x44);
        /* Serial 0 */
        byte |= (1<<6);
        pci_write_config8(dev, 0x44, byte);

        /* LPC Control 4 */
        byte = pci_read_config8(dev, 0x48);
        /* superio port 0x2e/4e enable */
        byte |=(1<<1)|(1<<0);
        pci_write_config8(dev, 0x48, byte);
}

static void bcm5785_enable_wdt_port_cf9(void)
{
        device_t dev;
        uint32_t dword;
        uint32_t dword_old;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);

        dword_old = pci_read_config32(dev, 0x4c);
        dword = dword_old | (1<<4); //enable Timer Func
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x4c, dword);
        }

        dword_old = pci_read_config32(dev, 0x6c);
        dword = dword_old | (1<<9); //unhide Timer Func in pci space
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x6c, dword);
        }

        dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);

        /* enable cf9 */
        pci_write_config8(dev, 0x40, (1<<2));
}

unsigned get_sbdn(unsigned bus)
{
        device_t dev;

        /* Find the device.
         * There can only be one bcm5785 on a hypertransport chain/bus.
         */
        dev = pci_locate_device_on_bus(
                PCI_ID(0x1166, 0x0036),
                bus);

        return (dev>>15) & 0x1f;

}

#define SB_VFSMAF 0

void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
{
	//ACPI Decode Enable
	outb(0x0e, 0xcd6);
	outb((1<<3), 0xcd7);

	// set port to 0x2060
	outb(0x67, 0xcd6);
	outb(0x60, 0xcd7);
        outb(0x68, 0xcd6);
        outb(0x20, 0xcd7);

	outb(0x69, 0xcd6);
	outb(7, 0xcd7);

	outb(0x64, 0xcd6);
	outb(9, 0xcd7);
}

void ldtstop_sb(void)
{
	outb(1, 0x2060);
}


void hard_reset(void)
{
        bcm5785_enable_wdt_port_cf9();

        set_bios_reset();

        /* full reset */
        outb(0x0a, 0x0cf9);
        outb(0x0e, 0x0cf9);
}

void soft_reset(void)
{
        bcm5785_enable_wdt_port_cf9();

        set_bios_reset();
#if 1
        /* link reset */
//        outb(0x02, 0x0cf9);
        outb(0x06, 0x0cf9);
#endif
}

static void bcm5785_enable_msg(void)
{
        device_t dev;
        uint32_t dword;
        uint32_t dword_old;
        uint8_t byte;

        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);

        byte = pci_read_config8(dev, 0x42);
        byte = (1<<1); //enable a20
        pci_write_config8(dev, 0x42, byte);

        dword_old = pci_read_config32(dev, 0x6c);
        // bit 5: enable A20 Message
        // bit 4: enable interrupt messages
        // bit 3: enable reset init message
        // bit 2: enable keyboard init message
        // bit 1: enable upsteam messages
        // bit 0: enable shutdowm message to init generation
        dword = dword_old | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0); // bit 1 and bit 4 must be set, otherwise interrupt msg will not be delivered to the processor
        if(dword != dword_old ) {
                pci_write_config32(dev, 0x6c, dword);
        }
}

static void bcm5785_early_setup(void)
{
        uint8_t byte;
        uint32_t dword;
        device_t dev;

//F0
        // enable device on bcm5785 at first
        dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
        dword = pci_read_config32(dev, 0x64);
        dword |=  (1<<15) | (1<<11) | (1<<3); // ioapci enable
        dword |= (1<<8); // USB enable
        dword |= /* (1<<27)|*/(1<<14); // IDE enable
        pci_write_config32(dev, 0x64, dword);

        byte = pci_read_config8(dev, 0x84);
        byte |= (1<<0); // SATA enable
        pci_write_config8(dev, 0x84, byte);

// WDT and cf9 for later in ramstage to call hard_reset
        bcm5785_enable_wdt_port_cf9();

        bcm5785_enable_msg();


// IDE related
	//F0
        byte = pci_read_config8(dev, 0x4e);
        byte |= (1<<4); //enable IDE ext regs
        pci_write_config8(dev, 0x4e, byte);

	//F1
        dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
        byte = pci_read_config8(dev, 0x48);
        byte &= ~1; // disable pri channel
        pci_write_config8(dev, 0x48, byte);
        pci_write_config8(dev, 0xb0, 0x01);
        pci_write_config8(dev, 0xb2, 0x02);
        byte = pci_read_config8(dev, 0x06);
        byte |= (1<<4); // so b0, b2 can not be changed from now
        pci_write_config8(dev, 0x06, byte);
        byte = pci_read_config8(dev, 0x49);
        byte |= 1; // enable second channel
        pci_write_config8(dev, 0x49, byte);

	//F2
        dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);

        byte = pci_read_config8(dev, 0x40);
        byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
        pci_write_config8(dev, 0x40, byte);

        pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end

// USB related
        pci_write_config8(dev, 0x90, 0x40);
        pci_write_config8(dev, 0x92, 0x06);
        pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
        pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
        pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
        pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
        pci_write_config8(dev, 0xb4, 0x40);
}
