* RS780M: 0x9612
* RS780MC:0x9613
* RS780E: 0x9615
+ * RS785G: 0x9710 - just works, not much tested
*/
#include <console/console.h>
#include <device/device.h>
#include <cpu/x86/msr.h>
#include "rs780.h"
-void set_pcie_reset();
-void set_pcie_dereset();
+void set_pcie_reset(void);
+void set_pcie_dereset(void);
+
+/* Trust the original resource allocation. Don't do it again. */
+#undef DONT_TRUST_RESOURCE_ALLOCATION
+//#define DONT_TRUST_RESOURCE_ALLOCATION
#define CLK_CNTL_INDEX 0x8
#define CLK_CNTL_DATA 0xC
/* The Integrated Info Table. */
ATOM_INTEGRATED_SYSTEM_INFO_V2 vgainfo;
+#ifdef UNUSED_CODE
static u32 clkind_read(device_t dev, u32 index)
{
u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
*(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
}
+#endif
static void clkind_write(device_t dev, u32 index, u32 data)
{
u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
- /* printk(BIOS_INFO, "gfx bar 2 %02x\n", gfx_bar2); */
+ /* printk(BIOS_DEBUG, "gfx bar 2 %02x\n", gfx_bar2); */
*(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
*(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
*/
static void rs780_gfx_read_resources(device_t dev)
{
- printk(BIOS_INFO, "rs780_gfx_read_resources.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_read_resources.\n");
/* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
MMIORANGE MMIO[8], CreativeMMIO[8];
-MMIORANGE* AllocMMIO(MMIORANGE* pMMIO)
+#define CIM_STATUS u32
+#define CIM_SUCCESS 0x00000000
+#define CIM_ERROR 0x80000000
+#define CIM_UNSUPPORTED 0x80000001
+#define CIM_DISABLEPORT 0x80000002
+
+#define MMIO_ATTRIB_NP_ONLY 1
+#define MMIO_ATTRIB_BOTTOM_TO_TOP 1<<1
+#define MMIO_ATTRIB_SKIP_ZERO 1<<2
+
+#ifdef DONT_TRUST_RESOURCE_ALLOCATION
+static MMIORANGE* AllocMMIO(MMIORANGE* pMMIO)
{
int i;
- for (i=0; i<8; i++)
- {
+ for (i=0; i<8; i++) {
if (pMMIO[i].Limit == 0)
return &pMMIO[i];
}
return 0;
}
-void FreeMMIO(MMIORANGE* pMMIO)
+
+static void FreeMMIO(MMIORANGE* pMMIO)
{
pMMIO->Base = 0;
pMMIO->Limit = 0;
}
-#define CIM_STATUS u32
-#define CIM_SUCCESS 0x00000000
-#define CIM_ERROR 0x80000000
-#define CIM_UNSUPPORTED 0x80000001
-#define CIM_DISABLEPORT 0x80000002
-
-#define MMIO_ATTRIB_NP_ONLY 1
-#define MMIO_ATTRIB_BOTTOM_TO_TOP 1<<1
-#define MMIO_ATTRIB_SKIP_ZERO 1<<2
-
-u32 SetMMIO(u32 Base, u32 Limit, u8 Attribute, MMIORANGE *pMMIO)
+static u32 SetMMIO(u32 Base, u32 Limit, u8 Attribute, MMIORANGE *pMMIO)
{
int i;
MMIORANGE * TempRange;
return 0;
}
-u8 FinalizeMMIO(MMIORANGE *pMMIO)
+static u8 FinalizeMMIO(MMIORANGE *pMMIO)
{
int i, j, n = 0;
for(i=0; i<8; i++)
return n;
}
-CIM_STATUS GetCreativeMMIO(MMIORANGE *pMMIO)
+static CIM_STATUS GetCreativeMMIO(MMIORANGE *pMMIO)
{
CIM_STATUS Status = CIM_UNSUPPORTED;
u8 Bus, Dev, Reg, BusStart, BusEnd;
return Status;
}
-void ProgramMMIO(MMIORANGE *pMMIO, u8 LinkID, u8 Attribute)
+static void ProgramMMIO(MMIORANGE *pMMIO, u8 LinkID, u8 Attribute)
{
int i, j, n = 7;
device_t k8_f1;
- u32 temp32;
k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
pci_write_config32(k8_f1, 0x80+MmioReg*8, Base);
}
}
+#endif
static void internal_gfx_pci_dev_init(struct device *dev)
{
volatile u32 * pointer;
int i;
u16 command;
- u32 value, temp, Base32, Limit32;
- CIM_STATUS Status;
+ u32 value;
u16 deviceid, vendorid;
device_t nb_dev = dev_find_slot(0, 0);
device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
- device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- device_t dev0x14 = dev_find_slot(0, PCI_DEVFN(0x14, 4));
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)dev->chip_info;
+ /* We definetely will use this in future. Just leave it here. */
+ /*struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)dev->chip_info;*/
deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
- printk(BIOS_INFO, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
+ printk(BIOS_DEBUG, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
deviceid, vendorid);
command = pci_read_config16(dev, 0x04);
value = nbmc_read_index(nb_dev, 0x10);
*(GpuF0MMReg + 0x2000/4) = 0x11;
*(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8);
- *(GpuF0MMReg + 0x2c04/4) = ((value&0xff0)<<8);
+ *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8);
*(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16);
*(GpuF0MMReg + 0x2000/4) = 0x00000011;
*(GpuF0MMReg + 0x200c/4) = 0x00000020;
//vgainfo.ulSystemConfig |= 1<<1 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1;
vgainfo.ulBootUpReqDisplayVector = 0; //?
vgainfo.ulOtherDisplayMisc = 0; //?
- vgainfo.ulDDISlot1Config = 0x000c0011; //0; //?
+ vgainfo.ulDDISlot1Config = 0x000c0011; //0; //VGA
+ //vgainfo.ulDDISlot1Config = 0x000c00FF; //0; //HDMI
vgainfo.ulDDISlot2Config = 0x00130022; //0; //?
vgainfo.ucMemoryType = 2;
/* UMA Channel Number: 1 or 2. */
pci_write_config8(dev, 0x4, temp8);
}
-#if 0 /* Trust the original resource allocation. Don't do it again. */
+#ifdef DONT_TRUST_RESOURCE_ALLOCATION
/* NB_SetupMGMMIO. */
/* clear MMIO and CreativeMMIO. */
{
u32 l_dword;
int i;
- device_t k8_f0 = 0, k8_f2 = 0;
device_t nb_dev = dev_find_slot(0, 0);
msr_t sysmem;
u32 FB_Start, FB_End;
#endif
- printk(BIOS_INFO, "rs780_internal_gfx_enable dev = 0x%p, nb_dev = 0x%p.\n", dev, nb_dev);
+ printk(BIOS_DEBUG, "rs780_internal_gfx_enable dev = 0x%p, nb_dev = 0x%p.\n", dev, nb_dev);
sysmem = rdmsr(0xc001001a);
- printk(BIOS_INFO, "sysmem = %x_%x\n", sysmem.hi, sysmem.lo);
+ printk(BIOS_DEBUG, "sysmem = %x_%x\n", sysmem.hi, sysmem.lo);
/* The system top memory in 780. */
pci_write_config32(nb_dev, 0x90, sysmem.lo);
/* LPC DMA Deadlock workaround? */
/* GFX_InitCommon*/
- k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
l_dword = pci_read_config32(k8_f0, 0x68);
l_dword &= ~(3 << 21);
l_dword |= (1 << 21);
#if (CONFIG_GFXUMA == 1)
/* GFX_InitUMA. */
/* Copy CPU DDR Controller to NB MC. */
- k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
for (i = 0; i < 12; i++)
{
l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
/* Set UMA in the 780 side. */
/* UMA start address, size. */
- /* The same value in spite of system memory size. */
- nbmc_write_index(nb_dev, 0x10, 0xcfffc000);
+ /* The UMA starts at 0xC0000000 of internal RS780 address space
+ [31:16] addr of last byte | [31:16] addr of first byte
+ */
+ nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000);
nbmc_write_index(nb_dev, 0x11, uma_memory_base);
nbmc_write_index(nb_dev, 0x12, 0);
nbmc_write_index(nb_dev, 0xf0, 256);
.vendor = PCI_VENDOR_ID_ATI,
.device = PCI_DEVICE_ID_ATI_RS780E_INT_GFX,
};
+static const struct pci_driver pcie_driver_785g __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS785G_INT_GFX,
+};
/* step 12 ~ step 14 from rpr */
static void single_port_configuration(device_t nb_dev, device_t dev)
struct southbridge_amd_rs780_config *cfg =
(struct southbridge_amd_rs780_config *)nb_dev->chip_info;
- printk(BIOS_INFO, "rs780_gfx_init single_port_configuration.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration.\n");
/* step 12 training, releases hold training for GFX port 0 (device 2) */
PcieReleasePortTraining(nb_dev, dev, 2);
result = PcieTrainPort(nb_dev, dev, 2);
- printk(BIOS_INFO, "rs780_gfx_init single_port_configuration step12.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step12.\n");
/* step 13 Power Down Control */
/* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
break;
}
}
- printk(BIOS_INFO, "rs780_gfx_init single_port_configuration step13.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step13.\n");
/* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
- printk(BIOS_INFO, "rs780_gfx_init single_port_configuration step14.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step14.\n");
}
static void dual_port_configuration(device_t nb_dev, device_t dev)
*/
void rs780_gfx_init(device_t nb_dev, device_t dev, u32 port)
{
- u16 reg16;
u32 reg32;
struct southbridge_amd_rs780_config *cfg =
(struct southbridge_amd_rs780_config *)nb_dev->chip_info;
- printk(BIOS_INFO, "rs780_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
+ printk(BIOS_DEBUG, "rs780_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
nb_dev, dev, port);
/* GFX Core Initialization */
//if (port == 2) return;
- /* step 1, lane reversal (only need if CMOS option is enabled) */
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- if (cfg->gfx_dual_slot)
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
- }
- printk(BIOS_INFO, "rs780_gfx_init step1.\n");
-
- /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
- /* AMD calls the configuration CrossFire */
- if (cfg->gfx_dual_slot)
- set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
- printk(BIOS_INFO, "rs780_gfx_init step2.\n");
-
/* step 2, TMDS, (only need if CMOS option is enabled) */
if (cfg->gfx_tmds) {
}
set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
1 << 6 | 1 << 8 | 1 << 10);
reg32 = nbmisc_read_index(nb_dev, 0x28);
- printk(BIOS_INFO, "misc 28 = %x\n", reg32);
+ printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
/* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 1 << 31);
set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
0);
reg32 = nbmisc_read_index(nb_dev, 0x28);
- printk(BIOS_INFO, "misc 28 = %x\n", reg32);
+ printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
/* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 0 << 31);
/* release hold training for device 2. GFX initialization is done. */
set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
- printk(BIOS_INFO, "rs780_gfx_init step7.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init step7.\n");
return;
}
/* 5.9.12.1 sets RCB timeout to be 25ms */
/* 5.9.12.2. RCB Cpl timeout on link down. */
set_pcie_enable_bits(dev, 0x70, 7 << 16 | 1 << 19, 4 << 16 | 1 << 19);
- printk(BIOS_INFO, "rs780_gfx_init step5.9.12.1.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.1.\n");
/* step 5.9.12.3 disables slave ordering logic */
set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
- printk(BIOS_INFO, "rs780_gfx_init step5.9.12.3.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.3.\n");
/* step 5.9.12.4 sets DMA payload size to 64 bytes */
set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
/* 5.9.12.9 CMGOOD_OVERRIDE for end point initiated lane degradation. */
set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
- printk(BIOS_INFO, "rs780_gfx_init step5.9.12.9.\n");
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.9.\n");
/* 5.9.12.10 Sets the timer in Config state from 20us to */
/* 5.9.12.11 De-asserts RX_EN in L0s. */
/* Single-port/Dual-port configureation. */
switch (cfg->gfx_dual_slot) {
case 0:
- single_port_configuration(nb_dev, dev);
+ /* step 1, lane reversal (only need if build config option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+
+ printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
+ if((dev->path.pci.devfn >> 3) == 2) {
+ single_port_configuration(nb_dev, dev);
+ } else {
+ set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
+ printk(BIOS_INFO, "Single port. Do nothing.\n"); // If dev3
+ }
+
break;
case 1:
+ /* step 1, lane reversal (only need if build config option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+ /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
+ /* AMD calls the configuration CrossFire */
+ set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
+ printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
+
+ printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
dual_port_configuration(nb_dev, dev);
break;
default:
- printk(BIOS_INFO, "Incorrect configuration of external gfx slot.\n");
+ printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
break;
}
}