From f7bc5f78abe92d1df2a0b2cd33353ee7d94a97ac Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Wed, 10 Mar 2010 10:23:24 +0000 Subject: [PATCH] kms rc10: Evergreen git-svn-id: svn://kolibrios.org@1430 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/include/drm/drm_crtc.h | 2 + drivers/include/drm/drm_edid.h | 3 + drivers/include/drm/drm_pciids.h | 35 + drivers/include/drm/radeon_drm.h | 1 + drivers/include/linux/i2c.h | 130 +- drivers/include/linux/kernel.h | 17 +- drivers/include/linux/module.h | 6 + drivers/include/linux/pci.h | 2 +- drivers/usb/uhci/detect.inc | 8 +- drivers/usb/uhci/usb.c | 1 - drivers/video/drm/drm_crtc_helper.c | 6 +- drivers/video/drm/drm_edid.c | 30 +- drivers/video/drm/drm_fb_helper.c | 9 +- drivers/video/drm/drm_mm.c | 3 +- drivers/video/drm/radeon/atom.c | 4 - drivers/video/drm/radeon/atombios.h | 5140 ++++++++++------- drivers/video/drm/radeon/atombios_crtc.c | 448 +- drivers/video/drm/radeon/atombios_dp.c | 48 +- drivers/video/drm/radeon/avivod.h | 2 + drivers/video/drm/radeon/evergreen.c | 720 +++ drivers/video/drm/radeon/evergreen_reg.h | 176 + drivers/video/drm/radeon/makefile | 2 + drivers/video/drm/radeon/r100.c | 180 +- drivers/video/drm/radeon/r200.c | 1 + drivers/video/drm/radeon/r300.c | 164 +- drivers/video/drm/radeon/r300_reg.h | 2 + drivers/video/drm/radeon/r420.c | 47 +- drivers/video/drm/radeon/r500_reg.h | 100 +- drivers/video/drm/radeon/r520.c | 25 +- drivers/video/drm/radeon/r600.c | 192 +- drivers/video/drm/radeon/r600_audio.c | 22 +- drivers/video/drm/radeon/r600d.h | 467 +- drivers/video/drm/radeon/radeon.h | 168 +- drivers/video/drm/radeon/radeon_agp.c | 6 +- drivers/video/drm/radeon/radeon_asic.h | 156 +- drivers/video/drm/radeon/radeon_atombios.c | 439 +- drivers/video/drm/radeon/radeon_bios.c | 45 +- drivers/video/drm/radeon/radeon_clocks.c | 16 +- drivers/video/drm/radeon/radeon_combios.c | 312 +- drivers/video/drm/radeon/radeon_connectors.c | 20 +- drivers/video/drm/radeon/radeon_device.c | 231 +- drivers/video/drm/radeon/radeon_display.c | 297 +- drivers/video/drm/radeon/radeon_encoders.c | 326 +- drivers/video/drm/radeon/radeon_family.h | 5 + drivers/video/drm/radeon/radeon_fb.c | 17 +- drivers/video/drm/radeon/radeon_gart.c | 38 +- drivers/video/drm/radeon/radeon_i2c.c | 749 ++- drivers/video/drm/radeon/radeon_legacy_crtc.c | 31 +- .../video/drm/radeon/radeon_legacy_encoders.c | 20 + drivers/video/drm/radeon/radeon_mode.h | 43 +- drivers/video/drm/radeon/radeon_object_kos.c | 6 +- drivers/video/drm/radeon/radeon_pm.c | 393 +- drivers/video/drm/radeon/radeon_reg.h | 50 +- drivers/video/drm/radeon/radeon_ring.c | 13 +- drivers/video/drm/radeon/rdisplay.c | 11 +- drivers/video/drm/radeon/rdisplay_kms.c | 4 +- drivers/video/drm/radeon/rs400.c | 39 +- drivers/video/drm/radeon/rs600.c | 50 +- drivers/video/drm/radeon/rs690.c | 41 +- drivers/video/drm/radeon/rv515.c | 31 +- drivers/video/drm/radeon/rv770.c | 199 +- drivers/video/drm/radeon/rv770d.h | 2 + 62 files changed, 8547 insertions(+), 3204 deletions(-) create mode 100644 drivers/video/drm/radeon/evergreen.c create mode 100644 drivers/video/drm/radeon/evergreen_reg.h diff --git a/drivers/include/drm/drm_crtc.h b/drivers/include/drm/drm_crtc.h index 5623adb69e..2258efd052 100644 --- a/drivers/include/drm/drm_crtc.h +++ b/drivers/include/drm/drm_crtc.h @@ -801,4 +801,6 @@ extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, bool interlaced, int margins); extern int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay); + +extern bool drm_edid_is_valid(struct edid *edid); #endif /* __DRM_CRTC_H__ */ diff --git a/drivers/include/drm/drm_edid.h b/drivers/include/drm/drm_edid.h index 7549b77248..e3fdcc6e97 100644 --- a/drivers/include/drm/drm_edid.h +++ b/drivers/include/drm/drm_edid.h @@ -201,4 +201,7 @@ struct edid { #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) +/* define the number of Extension EDID block */ +#define DRM_MAX_EDID_EXT_NUM 4 + #endif /* __DRM_EDID_H__ */ diff --git a/drivers/include/drm/drm_pciids.h b/drivers/include/drm/drm_pciids.h index dfa0566925..580423e195 100644 --- a/drivers/include/drm/drm_pciids.h +++ b/drivers/include/drm/drm_pciids.h @@ -141,6 +141,41 @@ {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x688A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x689d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x689e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68a0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68a8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/drivers/include/drm/radeon_drm.h b/drivers/include/drm/radeon_drm.h index 74e0132562..f56e160e4d 100644 --- a/drivers/include/drm/radeon_drm.h +++ b/drivers/include/drm/radeon_drm.h @@ -808,6 +808,7 @@ struct drm_radeon_gem_create { #define RADEON_TILING_SWAP_32BIT 0x8 #define RADEON_TILING_SURFACE 0x10 /* this object requires a surface * when mapped - i.e. front buffer */ +#define RADEON_TILING_MICRO_SQUARE 0x20 struct drm_radeon_gem_set_tiling { uint32_t handle; diff --git a/drivers/include/linux/i2c.h b/drivers/include/linux/i2c.h index 7159c2f47d..b3e35cfc93 100644 --- a/drivers/include/linux/i2c.h +++ b/drivers/include/linux/i2c.h @@ -28,6 +28,8 @@ #include #include +#include +#include #define I2C_NAME_SIZE 20 @@ -44,6 +46,84 @@ union i2c_smbus_data; extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); +/** + * struct i2c_driver - represent an I2C device driver + * @class: What kind of i2c device we instantiate (for detect) + * @attach_adapter: Callback for bus addition (for legacy drivers) + * @detach_adapter: Callback for bus removal (for legacy drivers) + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @shutdown: Callback for device shutdown + * @suspend: Callback for device suspend + * @resume: Callback for device resume + * @command: Callback for bus-wide signaling (optional) + * @driver: Device driver model driver + * @id_table: List of I2C devices supported by this driver + * @detect: Callback for device detection + * @address_list: The I2C addresses to probe (for detect) + * @clients: List of detected clients we created (for i2c-core use only) + * + * The driver.owner field should be set to the module owner of this driver. + * The driver.name field should be set to the name of this driver. + * + * For automatic device detection, both @detect and @address_data must + * be defined. @class should also be set, otherwise only devices forced + * with module parameters will be created. The detect function must + * fill at least the name field of the i2c_board_info structure it is + * handed upon successful detection, and possibly also the flags field. + * + * If @detect is missing, the driver will still work fine for enumerated + * devices. Detected devices simply won't be supported. This is expected + * for the many I2C/SMBus devices which can't be detected reliably, and + * the ones which can always be enumerated in practice. + * + * The i2c_client structure which is handed to the @detect callback is + * not a real i2c_client. It is initialized just enough so that you can + * call i2c_smbus_read_byte_data and friends on it. Don't do anything + * else with it. In particular, calling dev_dbg and friends on it is + * not allowed. + */ +struct i2c_driver { + unsigned int class; + + /* Notifies the driver that a new bus has appeared or is about to be + * removed. You should avoid using this if you can, it will probably + * be removed in a near future. + */ + int (*attach_adapter)(struct i2c_adapter *); + int (*detach_adapter)(struct i2c_adapter *); + + /* Standard driver model interfaces */ + int (*probe)(struct i2c_client *, const struct i2c_device_id *); + int (*remove)(struct i2c_client *); + + /* driver model interfaces that don't relate to enumeration */ + void (*shutdown)(struct i2c_client *); +// int (*suspend)(struct i2c_client *, pm_message_t mesg); + int (*resume)(struct i2c_client *); + + /* Alert callback, for example for the SMBus alert protocol. + * The format and meaning of the data value depends on the protocol. + * For the SMBus alert protocol, there is a single bit of data passed + * as the alert response's low bit ("event flag"). + */ + void (*alert)(struct i2c_client *, unsigned int data); + + /* a ioctl like command that can be used to perform specific functions + * with the device. + */ + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); + +// struct device_driver driver; + const struct i2c_device_id *id_table; + + /* Device detection callback for automatic device creation */ +// int (*detect)(struct i2c_client *, struct i2c_board_info *); + const unsigned short *address_list; + struct list_head clients; +}; +#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) + /** * struct i2c_client - represent an I2C slave device * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; @@ -69,13 +149,14 @@ struct i2c_client { /* _LOWER_ 7 bits */ char name[I2C_NAME_SIZE]; struct i2c_adapter *adapter; /* the adapter we sit on */ -// struct i2c_driver *driver; /* and our access routines */ + struct i2c_driver *driver; /* and our access routines */ // struct device dev; /* the device structure */ - int irq; /* irq issued by device (or -1) */ + int irq; /* irq issued by device (or -1) */ struct list_head detected; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) +extern struct i2c_client *i2c_verify_client(struct device *dev); /* * The following structs are for those who like to implement new bus drivers: @@ -111,17 +192,26 @@ struct i2c_adapter { void *algo_data; /* data fields that are valid for all devices */ - u8 level; /* nesting level for lockdep */ +// struct rt_mutex bus_lock; int timeout; /* in jiffies */ int retries; - // struct device dev; /* the adapter device */ + struct device dev; /* the adapter device */ int nr; char name[48]; }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) +static inline void *i2c_get_adapdata(const struct i2c_adapter *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} /*flags for the client struct: */ #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ @@ -136,17 +226,6 @@ struct i2c_adapter { #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ -/* i2c_client_address_data is the struct for holding default client - * addresses for a driver and for the parameters supplied on the - * command line - */ -struct i2c_client_address_data { - const unsigned short *normal_i2c; - const unsigned short *probe; - const unsigned short *ignore; - const unsigned short * const *forces; -}; - /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU @@ -275,25 +354,4 @@ union i2c_smbus_data { #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ #define I2C_SMBUS_I2C_BLOCK_DATA 8 - - - - - - - #endif /* _LINUX_I2C_H */ - - - - - - - - - - - - - - diff --git a/drivers/include/linux/kernel.h b/drivers/include/linux/kernel.h index 4cd96c8f52..5eb2373716 100644 --- a/drivers/include/linux/kernel.h +++ b/drivers/include/linux/kernel.h @@ -124,7 +124,22 @@ typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; struct file {}; struct vm_area_struct {}; struct address_space {}; -struct device {}; + +struct device +{ + struct device *parent; + void *driver_data; +}; + +static inline void dev_set_drvdata(struct device *dev, void *data) +{ + dev->driver_data = data; +} + +static inline void *dev_get_drvdata(struct device *dev) +{ + return dev->driver_data; +} #define preempt_disable() do { } while (0) #define preempt_enable_no_resched() do { } while (0) diff --git a/drivers/include/linux/module.h b/drivers/include/linux/module.h index df11732532..3ad224c6c7 100644 --- a/drivers/include/linux/module.h +++ b/drivers/include/linux/module.h @@ -4,12 +4,18 @@ #include #include +#include #define EXPORT_SYMBOL(x) #define MODULE_FIRMWARE(x) + +#define MODULE_AUTHOR(x) +#define MODULE_DESCRIPTION(x) +#define MODULE_LICENSE(x) + struct module {}; #endif /* _LINUX_MODULE_H */ diff --git a/drivers/include/linux/pci.h b/drivers/include/linux/pci.h index 68e17acf5c..b705ee1f4e 100644 --- a/drivers/include/linux/pci.h +++ b/drivers/include/linux/pci.h @@ -484,7 +484,7 @@ struct pci_dev { unsigned int no_d1d2:1; /* Only allow D0 and D3 */ // pci_channel_state_t error_state; /* current connectivity state */ -// struct device dev; /* Generic device interface */ + struct device dev; /* Generic device interface */ // int cfg_size; /* Size of configuration space */ diff --git a/drivers/usb/uhci/detect.inc b/drivers/usb/uhci/detect.inc index 0b7f43807f..eb892f35cb 100644 --- a/drivers/usb/uhci/detect.inc +++ b/drivers/usb/uhci/detect.inc @@ -1,6 +1,6 @@ -static Bool FindPciDevice() +Bool FindPciDevice() { Bool retval = FALSE; u32_t bus, last_bus; @@ -20,13 +20,17 @@ static Bool FindPciDevice() u32_t id; u16_t pcicmd; u16_t devclass; + u8_t interface; int i; + interface = PciRead8(bus,devfn, 0x09); devclass = PciRead16(bus,devfn, 0x0A); - if( devclass != 0x0C03) continue; + if( interface != 0) + continue; + pcicmd = PciRead16(bus,devfn, PCI_COMMAND); if (! pcicmd & PCI_COMMAND_IO) continue; diff --git a/drivers/usb/uhci/usb.c b/drivers/usb/uhci/usb.c index 2614bc2f5c..8169237963 100644 --- a/drivers/usb/uhci/usb.c +++ b/drivers/usb/uhci/usb.c @@ -12,7 +12,6 @@ #include "syscall.h" #include "usb.h" -static Bool FindPciDevice(); int __stdcall srv_usb(ioctl_t *io); diff --git a/drivers/video/drm/drm_crtc_helper.c b/drivers/video/drm/drm_crtc_helper.c index 1c3555612c..d29c94a7db 100644 --- a/drivers/video/drm/drm_crtc_helper.c +++ b/drivers/video/drm/drm_crtc_helper.c @@ -836,11 +836,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) mode_changed = true; } else if (set->fb == NULL) { mode_changed = true; - } else if ((set->fb->bits_per_pixel != - set->crtc->fb->bits_per_pixel) || - set->fb->depth != set->crtc->fb->depth) - fb_changed = true; - else + } else fb_changed = true; } diff --git a/drivers/video/drm/drm_edid.c b/drivers/video/drm/drm_edid.c index 8f1eb7e631..b2b4f9ac40 100644 --- a/drivers/video/drm/drm_edid.c +++ b/drivers/video/drm/drm_edid.c @@ -60,8 +60,7 @@ #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) /* use +hsync +vsync for detailed mode */ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) -/* define the number of Extension EDID block */ -#define MAX_EDID_EXT_NUM 4 + #define LEVEL_DMT 0 #define LEVEL_GTF 1 @@ -114,14 +113,14 @@ static const u8 edid_header[] = { }; /** - * edid_is_valid - sanity check EDID data + * drm_edid_is_valid - sanity check EDID data * @edid: EDID data * * Sanity check the EDID block by looking at the header, the version number * and the checksum. Return 0 if the EDID doesn't check out, or 1 if it's * valid. */ -static bool edid_is_valid(struct edid *edid) +bool drm_edid_is_valid(struct edid *edid) { int i, score = 0; u8 csum = 0; @@ -163,6 +162,7 @@ bad: } return 0; } +EXPORT_SYMBOL(drm_edid_is_valid); /** * edid_vendor - match a string against EDID's obfuscated vendor field @@ -1112,8 +1112,8 @@ static int add_detailed_info_eedid(struct drm_connector *connector, } /* Chose real EDID extension number */ - edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? - MAX_EDID_EXT_NUM : edid->extensions; + edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ? + DRM_MAX_EDID_EXT_NUM : edid->extensions; /* Find CEA extension */ for (i = 0; i < edid_ext_num; i++) { @@ -1195,7 +1195,7 @@ static int drm_ddc_read_edid(struct drm_connector *connector, for (i = 0; i < 4; i++) { if (drm_do_probe_ddc_edid(adapter, buf, len)) return -1; - if (edid_is_valid((struct edid *)buf)) + if (drm_edid_is_valid((struct edid *)buf)) return 0; } @@ -1220,7 +1220,7 @@ struct edid *drm_get_edid(struct drm_connector *connector, int ret; struct edid *edid; - edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1), + edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1), GFP_KERNEL); if (edid == NULL) { dev_warn(&connector->dev->pdev->dev, @@ -1238,14 +1238,14 @@ struct edid *drm_get_edid(struct drm_connector *connector, if (edid->extensions != 0) { int edid_ext_num = edid->extensions; - if (edid_ext_num > MAX_EDID_EXT_NUM) { + if (edid_ext_num > DRM_MAX_EDID_EXT_NUM) { dev_warn(&connector->dev->pdev->dev, "The number of extension(%d) is " "over max (%d), actually read number (%d)\n", - edid_ext_num, MAX_EDID_EXT_NUM, - MAX_EDID_EXT_NUM); + edid_ext_num, DRM_MAX_EDID_EXT_NUM, + DRM_MAX_EDID_EXT_NUM); /* Reset EDID extension number to be read */ - edid_ext_num = MAX_EDID_EXT_NUM; + edid_ext_num = DRM_MAX_EDID_EXT_NUM; } /* Read EDID including extensions too */ ret = drm_ddc_read_edid(connector, adapter, (char *)edid, @@ -1288,8 +1288,8 @@ bool drm_detect_hdmi_monitor(struct edid *edid) goto end; /* Chose real EDID extension number */ - edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? - MAX_EDID_EXT_NUM : edid->extensions; + edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ? + DRM_MAX_EDID_EXT_NUM : edid->extensions; /* Find CEA extension */ for (i = 0; i < edid_ext_num; i++) { @@ -1346,7 +1346,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (edid == NULL) { return 0; } - if (!edid_is_valid(edid)) { + if (!drm_edid_is_valid(edid)) { dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", drm_get_connector_name(connector)); return 0; diff --git a/drivers/video/drm/drm_fb_helper.c b/drivers/video/drm/drm_fb_helper.c index 3b1858db3f..141f2978d7 100644 --- a/drivers/video/drm/drm_fb_helper.c +++ b/drivers/video/drm/drm_fb_helper.c @@ -27,6 +27,7 @@ * Dave Airlie * Jesse Barnes */ +#include //#include #include #include "drmP.h" @@ -34,9 +35,9 @@ #include "drm_fb_helper.h" #include "drm_crtc_helper.h" -//MODULE_AUTHOR("David Airlie, Jesse Barnes"); -//MODULE_DESCRIPTION("DRM KMS helper"); -//MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("David Airlie, Jesse Barnes"); +MODULE_DESCRIPTION("DRM KMS helper"); +MODULE_LICENSE("GPL and additional rights"); static LIST_HEAD(kernel_fb_helper_list); @@ -480,7 +481,7 @@ int drm_fb_helper_set_par(struct fb_info *info) int i; if (var->pixclock != 0) { - DRM_ERROR("PIXEL CLCOK SET\n"); + DRM_ERROR("PIXEL CLOCK SET\n"); return -EINVAL; } diff --git a/drivers/video/drm/drm_mm.c b/drivers/video/drm/drm_mm.c index 69ace53399..d01f25a677 100644 --- a/drivers/video/drm/drm_mm.c +++ b/drivers/video/drm/drm_mm.c @@ -402,7 +402,8 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, wasted += alignment - tmp; } - if (entry->size >= size + wasted) { + if (entry->size >= size + wasted && + (entry->start + wasted + size) <= end) { if (!best_match) return entry; if (entry->size < best_size) { diff --git a/drivers/video/drm/radeon/atom.c b/drivers/video/drm/radeon/atom.c index c468c4746f..c32bbf1a2b 100644 --- a/drivers/video/drm/radeon/atom.c +++ b/drivers/video/drm/radeon/atom.c @@ -881,8 +881,6 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) uint8_t attr = U8((*ptr)++), shift; uint32_t saved, dst; int dptr = *ptr; - attr &= 0x38; - attr |= atom_def_dst[attr >> 3] << 6; SDEBUG(" dst: "); dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); shift = atom_get_src(ctx, attr, ptr); @@ -897,8 +895,6 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) uint8_t attr = U8((*ptr)++), shift; uint32_t saved, dst; int dptr = *ptr; - attr &= 0x38; - attr |= atom_def_dst[attr >> 3] << 6; SDEBUG(" dst: "); dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); shift = atom_get_src(ctx, attr, ptr); diff --git a/drivers/video/drm/radeon/atombios.h b/drivers/video/drm/radeon/atombios.h index 3afa221789..076d73993a 100644 --- a/drivers/video/drm/radeon/atombios.h +++ b/drivers/video/drm/radeon/atombios.h @@ -20,10 +20,12 @@ * OTHER DEALINGS IN THE SOFTWARE. */ + /****************************************************************************/ /*Portion I: Definitions shared between VBIOS and Driver */ /****************************************************************************/ + #ifndef _ATOMBIOS_H #define _ATOMBIOS_H @@ -40,17 +42,17 @@ #endif #ifdef _H2INC -#ifndef ULONG -typedef unsigned long ULONG; -#endif + #ifndef ULONG + typedef unsigned long ULONG; + #endif -#ifndef UCHAR -typedef unsigned char UCHAR; -#endif + #ifndef UCHAR + typedef unsigned char UCHAR; + #endif -#ifndef USHORT -typedef unsigned short USHORT; -#endif + #ifndef USHORT + typedef unsigned short USHORT; + #endif #endif #define ATOM_DAC_A 0 @@ -59,12 +61,19 @@ typedef unsigned short USHORT; #define ATOM_CRTC1 0 #define ATOM_CRTC2 1 +#define ATOM_CRTC3 2 +#define ATOM_CRTC4 3 +#define ATOM_CRTC5 4 +#define ATOM_CRTC6 5 +#define ATOM_CRTC_INVALID 0xFF #define ATOM_DIGA 0 #define ATOM_DIGB 1 #define ATOM_PPLL1 0 #define ATOM_PPLL2 1 +#define ATOM_DCPLL 2 +#define ATOM_PPLL_INVALID 0xFF #define ATOM_SCALER1 0 #define ATOM_SCALER2 1 @@ -82,6 +91,7 @@ typedef unsigned short USHORT; #define ATOM_LCD_SELFTEST_START (ATOM_DISABLE+5) #define ATOM_LCD_SELFTEST_STOP (ATOM_ENABLE+5) #define ATOM_ENCODER_INIT (ATOM_DISABLE+7) +#define ATOM_GET_STATUS (ATOM_DISABLE+8) #define ATOM_BLANKING 1 #define ATOM_BLANKING_OFF 0 @@ -134,6 +144,7 @@ typedef unsigned short USHORT; #define ATOM_PANEL_MISC_TEMPORAL 0x00000040 #define ATOM_PANEL_MISC_API_ENABLED 0x00000080 + #define MEMTYPE_DDR1 "DDR1" #define MEMTYPE_DDR2 "DDR2" #define MEMTYPE_DDR3 "DDR3" @@ -145,14 +156,14 @@ typedef unsigned short USHORT; /* Maximum size of that FireGL flag string */ -#define ATOM_FIREGL_FLAG_STRING "FGL" /* Flag used to enable FireGL Support */ -#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 3 /* sizeof( ATOM_FIREGL_FLAG_STRING ) */ +#define ATOM_FIREGL_FLAG_STRING "FGL" //Flag used to enable FireGL Support +#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 3 //sizeof( ATOM_FIREGL_FLAG_STRING ) -#define ATOM_FAKE_DESKTOP_STRING "DSK" /* Flag used to enable mobile ASIC on Desktop */ +#define ATOM_FAKE_DESKTOP_STRING "DSK" //Flag used to enable mobile ASIC on Desktop #define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING -#define ATOM_M54T_FLAG_STRING "M54T" /* Flag used to enable M54T Support */ -#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING 4 /* sizeof( ATOM_M54T_FLAG_STRING ) */ +#define ATOM_M54T_FLAG_STRING "M54T" //Flag used to enable M54T Support +#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING 4 //sizeof( ATOM_M54T_FLAG_STRING ) #define HW_ASSISTED_I2C_STATUS_FAILURE 2 #define HW_ASSISTED_I2C_STATUS_SUCCESS 1 @@ -173,14 +184,16 @@ typedef unsigned short USHORT; Every table pointed _ATOM_MASTER_DATA_TABLE has this common header. And the pointer actually points to this header. */ -typedef struct _ATOM_COMMON_TABLE_HEADER { +typedef struct _ATOM_COMMON_TABLE_HEADER +{ USHORT usStructureSize; UCHAR ucTableFormatRevision; /*Change it when the Parser is not backward compatible */ UCHAR ucTableContentRevision; /*Change it only when the table needs to change but the firmware */ /*Image can't be updated, while Driver needs to carry the new table! */ -} ATOM_COMMON_TABLE_HEADER; +}ATOM_COMMON_TABLE_HEADER; -typedef struct _ATOM_ROM_HEADER { +typedef struct _ATOM_ROM_HEADER +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR uaFirmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios, atombios should init it as "ATOM", don't change the position */ @@ -199,333 +212,374 @@ typedef struct _ATOM_ROM_HEADER { USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */ UCHAR ucExtendedFunctionCode; UCHAR ucReserved; -} ATOM_ROM_HEADER; +}ATOM_ROM_HEADER; /*==============================Command Table Portion==================================== */ #ifdef UEFI_BUILD -#define UTEMP USHORT -#define USHORT void* + #define UTEMP USHORT + #define USHORT void* #endif -typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES { - USHORT ASIC_Init; /* Function Table, used by various SW components,latest version 1.1 */ - USHORT GetDisplaySurfaceSize; /* Atomic Table, Used by Bios when enabling HW ICON */ - USHORT ASIC_RegistersInit; /* Atomic Table, indirectly used by various SW components,called from ASIC_Init */ - USHORT VRAM_BlockVenderDetection; /* Atomic Table, used only by Bios */ - USHORT DIGxEncoderControl; /* Only used by Bios */ - USHORT MemoryControllerInit; /* Atomic Table, indirectly used by various SW components,called from ASIC_Init */ - USHORT EnableCRTCMemReq; /* Function Table,directly used by various SW components,latest version 2.1 */ - USHORT MemoryParamAdjust; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock if needed */ - USHORT DVOEncoderControl; /* Function Table,directly used by various SW components,latest version 1.2 */ - USHORT GPIOPinControl; /* Atomic Table, only used by Bios */ - USHORT SetEngineClock; /*Function Table,directly used by various SW components,latest version 1.1 */ - USHORT SetMemoryClock; /* Function Table,directly used by various SW components,latest version 1.1 */ - USHORT SetPixelClock; /*Function Table,directly used by various SW components,latest version 1.2 */ - USHORT DynamicClockGating; /* Atomic Table, indirectly used by various SW components,called from ASIC_Init */ - USHORT ResetMemoryDLL; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ - USHORT ResetMemoryDevice; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ +typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ + USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 + USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON + USHORT ASIC_RegistersInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT VRAM_BlockVenderDetection; //Atomic Table, used only by Bios + USHORT DIGxEncoderControl; //Only used by Bios + USHORT MemoryControllerInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT EnableCRTCMemReq; //Function Table,directly used by various SW components,latest version 2.1 + USHORT MemoryParamAdjust; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock if needed + USHORT DVOEncoderControl; //Function Table,directly used by various SW components,latest version 1.2 + USHORT GPIOPinControl; //Atomic Table, only used by Bios + USHORT SetEngineClock; //Function Table,directly used by various SW components,latest version 1.1 + USHORT SetMemoryClock; //Function Table,directly used by various SW components,latest version 1.1 + USHORT SetPixelClock; //Function Table,directly used by various SW components,latest version 1.2 + USHORT DynamicClockGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT ResetMemoryDLL; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT ResetMemoryDevice; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock USHORT MemoryPLLInit; - USHORT AdjustDisplayPll; /* only used by Bios */ - USHORT AdjustMemoryController; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ - USHORT EnableASIC_StaticPwrMgt; /* Atomic Table, only used by Bios */ - USHORT ASIC_StaticPwrMgtStatusChange; /* Obsolete, only used by Bios */ - USHORT DAC_LoadDetection; /* Atomic Table, directly used by various SW components,latest version 1.2 */ - USHORT LVTMAEncoderControl; /* Atomic Table,directly used by various SW components,latest version 1.3 */ - USHORT LCD1OutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT DAC1EncoderControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT DAC2EncoderControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT DVOOutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT CV1OutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT GetConditionalGoldenSetting; /* only used by Bios */ - USHORT TVEncoderControl; /* Function Table,directly used by various SW components,latest version 1.1 */ - USHORT TMDSAEncoderControl; /* Atomic Table, directly used by various SW components,latest version 1.3 */ - USHORT LVDSEncoderControl; /* Atomic Table, directly used by various SW components,latest version 1.3 */ - USHORT TV1OutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT EnableScaler; /* Atomic Table, used only by Bios */ - USHORT BlankCRTC; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT EnableCRTC; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT GetPixelClock; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT EnableVGA_Render; /* Function Table,directly used by various SW components,latest version 1.1 */ - USHORT EnableVGA_Access; /* Obsolete , only used by Bios */ - USHORT SetCRTC_Timing; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT SetCRTC_OverScan; /* Atomic Table, used by various SW components,latest version 1.1 */ - USHORT SetCRTC_Replication; /* Atomic Table, used only by Bios */ - USHORT SelectCRTC_Source; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT EnableGraphSurfaces; /* Atomic Table, used only by Bios */ + USHORT AdjustDisplayPll; //only used by Bios + USHORT AdjustMemoryController; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT EnableASIC_StaticPwrMgt; //Atomic Table, only used by Bios + USHORT ASIC_StaticPwrMgtStatusChange; //Obsolete , only used by Bios + USHORT DAC_LoadDetection; //Atomic Table, directly used by various SW components,latest version 1.2 + USHORT LVTMAEncoderControl; //Atomic Table,directly used by various SW components,latest version 1.3 + USHORT LCD1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC1EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC2EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DVOOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT CV1OutputControl; //Atomic Table, Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead + USHORT GetConditionalGoldenSetting; //only used by Bios + USHORT TVEncoderControl; //Function Table,directly used by various SW components,latest version 1.1 + USHORT TMDSAEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 + USHORT LVDSEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3 + USHORT TV1OutputControl; //Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead + USHORT EnableScaler; //Atomic Table, used only by Bios + USHORT BlankCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT EnableCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT GetPixelClock; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT EnableVGA_Render; //Function Table,directly used by various SW components,latest version 1.1 + USHORT GetSCLKOverMCLKRatio; //Atomic Table, only used by Bios + USHORT SetCRTC_Timing; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT SetCRTC_OverScan; //Atomic Table, used by various SW components,latest version 1.1 + USHORT SetCRTC_Replication; //Atomic Table, used only by Bios + USHORT SelectCRTC_Source; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT EnableGraphSurfaces; //Atomic Table, used only by Bios USHORT UpdateCRTC_DoubleBufferRegisters; - USHORT LUT_AutoFill; /* Atomic Table, only used by Bios */ - USHORT EnableHW_IconCursor; /* Atomic Table, only used by Bios */ - USHORT GetMemoryClock; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT GetEngineClock; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT SetCRTC_UsingDTDTiming; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT ExternalEncoderControl; /* Atomic Table, directly used by various SW components,latest version 2.1 */ - USHORT LVTMAOutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT VRAM_BlockDetectionByStrap; /* Atomic Table, used only by Bios */ - USHORT MemoryCleanUp; /* Atomic Table, only used by Bios */ - USHORT ProcessI2cChannelTransaction; /* Function Table,only used by Bios */ - USHORT WriteOneByteToHWAssistedI2C; /* Function Table,indirectly used by various SW components */ - USHORT ReadHWAssistedI2CStatus; /* Atomic Table, indirectly used by various SW components */ - USHORT SpeedFanControl; /* Function Table,indirectly used by various SW components,called from ASIC_Init */ - USHORT PowerConnectorDetection; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT MC_Synchronization; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ - USHORT ComputeMemoryEnginePLL; /* Atomic Table, indirectly used by various SW components,called from SetMemory/EngineClock */ - USHORT MemoryRefreshConversion; /* Atomic Table, indirectly used by various SW components,called from SetMemory or SetEngineClock */ - USHORT VRAM_GetCurrentInfoBlock; /* Atomic Table, used only by Bios */ - USHORT DynamicMemorySettings; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ - USHORT MemoryTraining; /* Atomic Table, used only by Bios */ - USHORT EnableSpreadSpectrumOnPPLL; /* Atomic Table, directly used by various SW components,latest version 1.2 */ - USHORT TMDSAOutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT SetVoltage; /* Function Table,directly and/or indirectly used by various SW components,latest version 1.1 */ - USHORT DAC1OutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT DAC2OutputControl; /* Atomic Table, directly used by various SW components,latest version 1.1 */ - USHORT SetupHWAssistedI2CStatus; /* Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" */ - USHORT ClockSource; /* Atomic Table, indirectly used by various SW components,called from ASIC_Init */ - USHORT MemoryDeviceInit; /* Atomic Table, indirectly used by various SW components,called from SetMemoryClock */ - USHORT EnableYUV; /* Atomic Table, indirectly used by various SW components,called from EnableVGARender */ - USHORT DIG1EncoderControl; /* Atomic Table,directly used by various SW components,latest version 1.1 */ - USHORT DIG2EncoderControl; /* Atomic Table,directly used by various SW components,latest version 1.1 */ - USHORT DIG1TransmitterControl; /* Atomic Table,directly used by various SW components,latest version 1.1 */ - USHORT DIG2TransmitterControl; /* Atomic Table,directly used by various SW components,latest version 1.1 */ - USHORT ProcessAuxChannelTransaction; /* Function Table,only used by Bios */ - USHORT DPEncoderService; /* Function Table,only used by Bios */ -} ATOM_MASTER_LIST_OF_COMMAND_TABLES; + USHORT LUT_AutoFill; //Atomic Table, only used by Bios + USHORT EnableHW_IconCursor; //Atomic Table, only used by Bios + USHORT GetMemoryClock; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT GetEngineClock; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT SetCRTC_UsingDTDTiming; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT ExternalEncoderControl; //Atomic Table, directly used by various SW components,latest version 2.1 + USHORT LVTMAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT VRAM_BlockDetectionByStrap; //Atomic Table, used only by Bios + USHORT MemoryCleanUp; //Atomic Table, only used by Bios + USHORT ProcessI2cChannelTransaction; //Function Table,only used by Bios + USHORT WriteOneByteToHWAssistedI2C; //Function Table,indirectly used by various SW components + USHORT ReadHWAssistedI2CStatus; //Atomic Table, indirectly used by various SW components + USHORT SpeedFanControl; //Function Table,indirectly used by various SW components,called from ASIC_Init + USHORT PowerConnectorDetection; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT MC_Synchronization; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT ComputeMemoryEnginePLL; //Atomic Table, indirectly used by various SW components,called from SetMemory/EngineClock + USHORT MemoryRefreshConversion; //Atomic Table, indirectly used by various SW components,called from SetMemory or SetEngineClock + USHORT VRAM_GetCurrentInfoBlock; //Atomic Table, used only by Bios + USHORT DynamicMemorySettings; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT MemoryTraining; //Atomic Table, used only by Bios + USHORT EnableSpreadSpectrumOnPPLL; //Atomic Table, directly used by various SW components,latest version 1.2 + USHORT TMDSAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT SetVoltage; //Function Table,directly and/or indirectly used by various SW components,latest version 1.1 + USHORT DAC1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT DAC2OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 + USHORT SetupHWAssistedI2CStatus; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" + USHORT ClockSource; //Atomic Table, indirectly used by various SW components,called from ASIC_Init + USHORT MemoryDeviceInit; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock + USHORT EnableYUV; //Atomic Table, indirectly used by various SW components,called from EnableVGARender + USHORT DIG1EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG2EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG1TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT DIG2TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 + USHORT ProcessAuxChannelTransaction; //Function Table,only used by Bios + USHORT DPEncoderService; //Function Table,only used by Bios +}ATOM_MASTER_LIST_OF_COMMAND_TABLES; -/* For backward compatible */ +// For backward compatible #define ReadEDIDFromHWAssistedI2C ProcessI2cChannelTransaction #define UNIPHYTransmitterControl DIG1TransmitterControl #define LVTMATransmitterControl DIG2TransmitterControl #define SetCRTC_DPM_State GetConditionalGoldenSetting #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange +#define HPDInterruptService ReadHWAssistedI2CStatus +#define EnableVGA_Access GetSCLKOverMCLKRatio -typedef struct _ATOM_MASTER_COMMAND_TABLE { +typedef struct _ATOM_MASTER_COMMAND_TABLE +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables; -} ATOM_MASTER_COMMAND_TABLE; +}ATOM_MASTER_COMMAND_TABLE; /****************************************************************************/ -/* Structures used in every command table */ +// Structures used in every command table /****************************************************************************/ -typedef struct _ATOM_TABLE_ATTRIBUTE { +typedef struct _ATOM_TABLE_ATTRIBUTE +{ #if ATOM_BIG_ENDIAN - USHORT UpdatedByUtility:1; /* [15]=Table updated by utility flag */ - USHORT PS_SizeInBytes:7; /* [14:8]=Size of parameter space in Bytes (multiple of a dword), */ - USHORT WS_SizeInBytes:8; /* [7:0]=Size of workspace in Bytes (in multiple of a dword), */ + USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag + USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), + USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), #else - USHORT WS_SizeInBytes:8; /* [7:0]=Size of workspace in Bytes (in multiple of a dword), */ - USHORT PS_SizeInBytes:7; /* [14:8]=Size of parameter space in Bytes (multiple of a dword), */ - USHORT UpdatedByUtility:1; /* [15]=Table updated by utility flag */ + USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), + USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), + USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag #endif -} ATOM_TABLE_ATTRIBUTE; +}ATOM_TABLE_ATTRIBUTE; -typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS { +typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS +{ ATOM_TABLE_ATTRIBUTE sbfAccess; USHORT susAccess; -} ATOM_TABLE_ATTRIBUTE_ACCESS; +}ATOM_TABLE_ATTRIBUTE_ACCESS; /****************************************************************************/ -/* Common header for all command tables. */ -/* Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. */ -/* And the pointer actually points to this header. */ +// Common header for all command tables. +// Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. +// And the pointer actually points to this header. /****************************************************************************/ -typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER { +typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER +{ ATOM_COMMON_TABLE_HEADER CommonHeader; ATOM_TABLE_ATTRIBUTE TableAttribute; -} ATOM_COMMON_ROM_COMMAND_TABLE_HEADER; +}ATOM_COMMON_ROM_COMMAND_TABLE_HEADER; /****************************************************************************/ -/* Structures used by ComputeMemoryEnginePLLTable */ +// Structures used by ComputeMemoryEnginePLLTable /****************************************************************************/ #define COMPUTE_MEMORY_PLL_PARAM 1 #define COMPUTE_ENGINE_PLL_PARAM 2 -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS { - ULONG ulClock; /* When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div */ - UCHAR ucAction; /* 0:reserved //1:Memory //2:Engine */ - UCHAR ucReserved; /* may expand to return larger Fbdiv later */ - UCHAR ucFbDiv; /* return value */ - UCHAR ucPostDiv; /* return value */ -} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS; +typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS +{ + ULONG ulClock; //When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div + UCHAR ucAction; //0:reserved //1:Memory //2:Engine + UCHAR ucReserved; //may expand to return larger Fbdiv later + UCHAR ucFbDiv; //return value + UCHAR ucPostDiv; //return value +}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS; -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 { - ULONG ulClock; /* When return, [23:0] return real clock */ - UCHAR ucAction; /* 0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register */ - USHORT usFbDiv; /* return Feedback value to be written to register */ - UCHAR ucPostDiv; /* return post div to be written to register */ -} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2; +typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 +{ + ULONG ulClock; //When return, [23:0] return real clock + UCHAR ucAction; //0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register + USHORT usFbDiv; //return Feedback value to be written to register + UCHAR ucPostDiv; //return post div to be written to register +}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2; #define COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS -#define SET_CLOCK_FREQ_MASK 0x00FFFFFF /* Clock change tables only take bit [23:0] as the requested clock value */ -#define USE_NON_BUS_CLOCK_MASK 0x01000000 /* Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) */ -#define USE_MEMORY_SELF_REFRESH_MASK 0x02000000 /* Only applicable to memory clock change, when set, using memory self refresh during clock transition */ -#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04000000 /* Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change */ -#define FIRST_TIME_CHANGE_CLOCK 0x08000000 /* Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup */ -#define SKIP_SW_PROGRAM_PLL 0x10000000 /* Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL */ + +#define SET_CLOCK_FREQ_MASK 0x00FFFFFF //Clock change tables only take bit [23:0] as the requested clock value +#define USE_NON_BUS_CLOCK_MASK 0x01000000 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) +#define USE_MEMORY_SELF_REFRESH_MASK 0x02000000 //Only applicable to memory clock change, when set, using memory self refresh during clock transition +#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04000000 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change +#define FIRST_TIME_CHANGE_CLOCK 0x08000000 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup +#define SKIP_SW_PROGRAM_PLL 0x10000000 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL #define USE_SS_ENABLED_PIXEL_CLOCK USE_NON_BUS_CLOCK_MASK -#define b3USE_NON_BUS_CLOCK_MASK 0x01 /* Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) */ -#define b3USE_MEMORY_SELF_REFRESH 0x02 /* Only applicable to memory clock change, when set, using memory self refresh during clock transition */ -#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04 /* Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change */ -#define b3FIRST_TIME_CHANGE_CLOCK 0x08 /* Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup */ -#define b3SKIP_SW_PROGRAM_PLL 0x10 /* Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL */ +#define b3USE_NON_BUS_CLOCK_MASK 0x01 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) +#define b3USE_MEMORY_SELF_REFRESH 0x02 //Only applicable to memory clock change, when set, using memory self refresh during clock transition +#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change +#define b3FIRST_TIME_CHANGE_CLOCK 0x08 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup +#define b3SKIP_SW_PROGRAM_PLL 0x10 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL -typedef struct _ATOM_COMPUTE_CLOCK_FREQ { +typedef struct _ATOM_COMPUTE_CLOCK_FREQ +{ #if ATOM_BIG_ENDIAN - ULONG ulComputeClockFlag:8; /* =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM */ - ULONG ulClockFreq:24; /* in unit of 10kHz */ + ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM + ULONG ulClockFreq:24; // in unit of 10kHz #else - ULONG ulClockFreq:24; /* in unit of 10kHz */ - ULONG ulComputeClockFlag:8; /* =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM */ + ULONG ulClockFreq:24; // in unit of 10kHz + ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM #endif -} ATOM_COMPUTE_CLOCK_FREQ; +}ATOM_COMPUTE_CLOCK_FREQ; -typedef struct _ATOM_S_MPLL_FB_DIVIDER { +typedef struct _ATOM_S_MPLL_FB_DIVIDER +{ USHORT usFbDivFrac; USHORT usFbDiv; -} ATOM_S_MPLL_FB_DIVIDER; +}ATOM_S_MPLL_FB_DIVIDER; -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 { - union { - ATOM_COMPUTE_CLOCK_FREQ ulClock; /* Input Parameter */ - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; /* Output Parameter */ +typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 +{ + union + { + ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter + ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter }; - UCHAR ucRefDiv; /* Output Parameter */ - UCHAR ucPostDiv; /* Output Parameter */ - UCHAR ucCntlFlag; /* Output Parameter */ + UCHAR ucRefDiv; //Output Parameter + UCHAR ucPostDiv; //Output Parameter + UCHAR ucCntlFlag; //Output Parameter UCHAR ucReserved; -} COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3; +}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3; -/* ucCntlFlag */ +// ucCntlFlag #define ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN 1 #define ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE 2 #define ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE 4 +#define ATOM_PLL_CNTL_FLAG_SPLL_ISPARE_9 8 -typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER { + +// V4 are only used for APU which PLL outside GPU +typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 +{ +#if ATOM_BIG_ENDIAN + ULONG ucPostDiv; //return parameter: post divider which is used to program to register directly + ULONG ulClock:24; //Input= target clock, output = actual clock +#else + ULONG ulClock:24; //Input= target clock, output = actual clock + ULONG ucPostDiv; //return parameter: post divider which is used to program to register directly +#endif +}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4; + +typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER +{ ATOM_COMPUTE_CLOCK_FREQ ulClock; ULONG ulReserved[2]; -} DYNAMICE_MEMORY_SETTINGS_PARAMETER; +}DYNAMICE_MEMORY_SETTINGS_PARAMETER; -typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER { +typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER +{ ATOM_COMPUTE_CLOCK_FREQ ulClock; ULONG ulMemoryClock; ULONG ulReserved; -} DYNAMICE_ENGINE_SETTINGS_PARAMETER; +}DYNAMICE_ENGINE_SETTINGS_PARAMETER; /****************************************************************************/ -/* Structures used by SetEngineClockTable */ +// Structures used by SetEngineClockTable /****************************************************************************/ -typedef struct _SET_ENGINE_CLOCK_PARAMETERS { - ULONG ulTargetEngineClock; /* In 10Khz unit */ -} SET_ENGINE_CLOCK_PARAMETERS; +typedef struct _SET_ENGINE_CLOCK_PARAMETERS +{ + ULONG ulTargetEngineClock; //In 10Khz unit +}SET_ENGINE_CLOCK_PARAMETERS; -typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION { - ULONG ulTargetEngineClock; /* In 10Khz unit */ +typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION +{ + ULONG ulTargetEngineClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; -} SET_ENGINE_CLOCK_PS_ALLOCATION; +}SET_ENGINE_CLOCK_PS_ALLOCATION; /****************************************************************************/ -/* Structures used by SetMemoryClockTable */ +// Structures used by SetMemoryClockTable /****************************************************************************/ -typedef struct _SET_MEMORY_CLOCK_PARAMETERS { - ULONG ulTargetMemoryClock; /* In 10Khz unit */ -} SET_MEMORY_CLOCK_PARAMETERS; +typedef struct _SET_MEMORY_CLOCK_PARAMETERS +{ + ULONG ulTargetMemoryClock; //In 10Khz unit +}SET_MEMORY_CLOCK_PARAMETERS; -typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION { - ULONG ulTargetMemoryClock; /* In 10Khz unit */ +typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION +{ + ULONG ulTargetMemoryClock; //In 10Khz unit COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; -} SET_MEMORY_CLOCK_PS_ALLOCATION; +}SET_MEMORY_CLOCK_PS_ALLOCATION; /****************************************************************************/ -/* Structures used by ASIC_Init.ctb */ +// Structures used by ASIC_Init.ctb /****************************************************************************/ -typedef struct _ASIC_INIT_PARAMETERS { - ULONG ulDefaultEngineClock; /* In 10Khz unit */ - ULONG ulDefaultMemoryClock; /* In 10Khz unit */ -} ASIC_INIT_PARAMETERS; +typedef struct _ASIC_INIT_PARAMETERS +{ + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit +}ASIC_INIT_PARAMETERS; -typedef struct _ASIC_INIT_PS_ALLOCATION { +typedef struct _ASIC_INIT_PS_ALLOCATION +{ ASIC_INIT_PARAMETERS sASICInitClocks; - SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; /* Caller doesn't need to init this structure */ -} ASIC_INIT_PS_ALLOCATION; + SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; //Caller doesn't need to init this structure +}ASIC_INIT_PS_ALLOCATION; /****************************************************************************/ -/* Structure used by DynamicClockGatingTable.ctb */ +// Structure used by DynamicClockGatingTable.ctb /****************************************************************************/ -typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS { - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ +typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS +{ + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE UCHAR ucPadding[3]; -} DYNAMIC_CLOCK_GATING_PARAMETERS; +}DYNAMIC_CLOCK_GATING_PARAMETERS; #define DYNAMIC_CLOCK_GATING_PS_ALLOCATION DYNAMIC_CLOCK_GATING_PARAMETERS /****************************************************************************/ -/* Structure used by EnableASIC_StaticPwrMgtTable.ctb */ +// Structure used by EnableASIC_StaticPwrMgtTable.ctb /****************************************************************************/ -typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS { - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ +typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS +{ + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE UCHAR ucPadding[3]; -} ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS; +}ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS; #define ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS /****************************************************************************/ -/* Structures used by DAC_LoadDetectionTable.ctb */ +// Structures used by DAC_LoadDetectionTable.ctb /****************************************************************************/ -typedef struct _DAC_LOAD_DETECTION_PARAMETERS { - USHORT usDeviceID; /* {ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT} */ - UCHAR ucDacType; /* {ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC} */ - UCHAR ucMisc; /* Valid only when table revision =1.3 and above */ -} DAC_LOAD_DETECTION_PARAMETERS; +typedef struct _DAC_LOAD_DETECTION_PARAMETERS +{ + USHORT usDeviceID; //{ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT} + UCHAR ucDacType; //{ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC} + UCHAR ucMisc; //Valid only when table revision =1.3 and above +}DAC_LOAD_DETECTION_PARAMETERS; -/* DAC_LOAD_DETECTION_PARAMETERS.ucMisc */ +// DAC_LOAD_DETECTION_PARAMETERS.ucMisc #define DAC_LOAD_MISC_YPrPb 0x01 -typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION { +typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION +{ DAC_LOAD_DETECTION_PARAMETERS sDacload; - ULONG Reserved[2]; /* Don't set this one, allocation for EXT DAC */ -} DAC_LOAD_DETECTION_PS_ALLOCATION; + ULONG Reserved[2];// Don't set this one, allocation for EXT DAC +}DAC_LOAD_DETECTION_PS_ALLOCATION; /****************************************************************************/ -/* Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb */ +// Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb /****************************************************************************/ -typedef struct _DAC_ENCODER_CONTROL_PARAMETERS { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucDacStandard; /* See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0) */ - UCHAR ucAction; /* 0: turn off encoder */ - /* 1: setup and turn on encoder */ - /* 7: ATOM_ENCODER_INIT Initialize DAC */ -} DAC_ENCODER_CONTROL_PARAMETERS; +typedef struct _DAC_ENCODER_CONTROL_PARAMETERS +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + UCHAR ucDacStandard; // See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0) + UCHAR ucAction; // 0: turn off encoder + // 1: setup and turn on encoder + // 7: ATOM_ENCODER_INIT Initialize DAC +}DAC_ENCODER_CONTROL_PARAMETERS; #define DAC_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PARAMETERS /****************************************************************************/ -/* Structures used by DIG1EncoderControlTable */ -/* DIG2EncoderControlTable */ -/* ExternalEncoderControlTable */ +// Structures used by DIG1EncoderControlTable +// DIG2EncoderControlTable +// ExternalEncoderControlTable /****************************************************************************/ -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ +typedef struct _DIG_ENCODER_CONTROL_PARAMETERS +{ + USHORT usPixelClock; // in 10KHz; for bios convenient UCHAR ucConfig; - /* [2] Link Select: */ - /* =0: PHY linkA if bfLane<3 */ - /* =1: PHY linkB if bfLanes<3 */ - /* =0: PHY linkA+B if bfLanes=3 */ - /* [3] Transmitter Sel */ - /* =0: UNIPHY or PCIEPHY */ - /* =1: LVTMA */ - UCHAR ucAction; /* =0: turn off encoder */ - /* =1: turn on encoder */ + // [2] Link Select: + // =0: PHY linkA if bfLane<3 + // =1: PHY linkB if bfLanes<3 + // =0: PHY linkA+B if bfLanes=3 + // [3] Transmitter Sel + // =0: UNIPHY or PCIEPHY + // =1: LVTMA + UCHAR ucAction; // =0: turn off encoder + // =1: turn on encoder UCHAR ucEncoderMode; - /* =0: DP encoder */ - /* =1: LVDS encoder */ - /* =2: DVI encoder */ - /* =3: HDMI encoder */ - /* =4: SDVO encoder */ - UCHAR ucLaneNum; /* how many lanes to enable */ + // =0: DP encoder + // =1: LVDS encoder + // =2: DVI encoder + // =3: HDMI encoder + // =4: SDVO encoder + UCHAR ucLaneNum; // how many lanes to enable UCHAR ucReserved[2]; -} DIG_ENCODER_CONTROL_PARAMETERS; +}DIG_ENCODER_CONTROL_PARAMETERS; #define DIG_ENCODER_CONTROL_PS_ALLOCATION DIG_ENCODER_CONTROL_PARAMETERS #define EXTERNAL_ENCODER_CONTROL_PARAMETER DIG_ENCODER_CONTROL_PARAMETERS -/* ucConfig */ +//ucConfig #define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 #define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 #define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 @@ -539,52 +593,57 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS { #define ATOM_ENCODER_CONFIG_LVTMA 0x08 #define ATOM_ENCODER_CONFIG_TRANSMITTER1 0x00 #define ATOM_ENCODER_CONFIG_TRANSMITTER2 0x08 -#define ATOM_ENCODER_CONFIG_DIGB 0x80 /* VBIOS Internal use, outside SW should set this bit=0 */ -/* ucAction */ -/* ATOM_ENABLE: Enable Encoder */ -/* ATOM_DISABLE: Disable Encoder */ +#define ATOM_ENCODER_CONFIG_DIGB 0x80 // VBIOS Internal use, outside SW should set this bit=0 +// ucAction +// ATOM_ENABLE: Enable Encoder +// ATOM_DISABLE: Disable Encoder -/* ucEncoderMode */ +//ucEncoderMode #define ATOM_ENCODER_MODE_DP 0 #define ATOM_ENCODER_MODE_LVDS 1 #define ATOM_ENCODER_MODE_DVI 2 #define ATOM_ENCODER_MODE_HDMI 3 #define ATOM_ENCODER_MODE_SDVO 4 +#define ATOM_ENCODER_MODE_DP_AUDIO 5 #define ATOM_ENCODER_MODE_TV 13 #define ATOM_ENCODER_MODE_CV 14 #define ATOM_ENCODER_MODE_CRT 15 -typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 { +typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 +{ #if ATOM_BIG_ENDIAN UCHAR ucReserved1:2; - UCHAR ucTransmitterSel:2; /* =0: UniphyAB, =1: UniphyCD =2: UniphyEF */ - UCHAR ucLinkSel:1; /* =0: linkA/C/E =1: linkB/D/F */ + UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF + UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F UCHAR ucReserved:1; - UCHAR ucDPLinkRate:1; /* =0: 1.62Ghz, =1: 2.7Ghz */ + UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz #else - UCHAR ucDPLinkRate:1; /* =0: 1.62Ghz, =1: 2.7Ghz */ + UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz UCHAR ucReserved:1; - UCHAR ucLinkSel:1; /* =0: linkA/C/E =1: linkB/D/F */ - UCHAR ucTransmitterSel:2; /* =0: UniphyAB, =1: UniphyCD =2: UniphyEF */ + UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F + UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF UCHAR ucReserved1:2; #endif -} ATOM_DIG_ENCODER_CONFIG_V2; +}ATOM_DIG_ENCODER_CONFIG_V2; -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ + +typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 +{ + USHORT usPixelClock; // in 10KHz; for bios convenient ATOM_DIG_ENCODER_CONFIG_V2 acConfig; UCHAR ucAction; UCHAR ucEncoderMode; - /* =0: DP encoder */ - /* =1: LVDS encoder */ - /* =2: DVI encoder */ - /* =3: HDMI encoder */ - /* =4: SDVO encoder */ - UCHAR ucLaneNum; /* how many lanes to enable */ - UCHAR ucReserved[2]; -} DIG_ENCODER_CONTROL_PARAMETERS_V2; + // =0: DP encoder + // =1: LVDS encoder + // =2: DVI encoder + // =3: HDMI encoder + // =4: SDVO encoder + UCHAR ucLaneNum; // how many lanes to enable + UCHAR ucStatus; // = DP_LINK_TRAINING_COMPLETE or DP_LINK_TRAINING_INCOMPLETE, only used by VBIOS with command ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS + UCHAR ucReserved; +}DIG_ENCODER_CONTROL_PARAMETERS_V2; -/* ucConfig */ +//ucConfig #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_MASK 0x01 #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_1_62GHZ 0x00 #define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_2_70GHZ 0x01 @@ -596,47 +655,111 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 { #define ATOM_ENCODER_CONFIG_V2_TRANSMITTER2 0x08 #define ATOM_ENCODER_CONFIG_V2_TRANSMITTER3 0x10 +// ucAction: +// ATOM_DISABLE +// ATOM_ENABLE +#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START 0x08 +#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1 0x09 +#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2 0x0a +#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE 0x0b +#define ATOM_ENCODER_CMD_DP_VIDEO_OFF 0x0c +#define ATOM_ENCODER_CMD_DP_VIDEO_ON 0x0d +#define ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS 0x0e +#define ATOM_ENCODER_CMD_SETUP 0x0f + +// ucStatus +#define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE 0x10 +#define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE 0x00 + +// Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver +typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 +{ +#if ATOM_BIG_ENDIAN + UCHAR ucReserved1:1; + UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F + UCHAR ucReserved:3; + UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz +#else + UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz + UCHAR ucReserved:3; + UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F + UCHAR ucReserved1:1; +#endif +}ATOM_DIG_ENCODER_CONFIG_V3; + +#define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL 0x70 + + +typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + ATOM_DIG_ENCODER_CONFIG_V3 acConfig; + UCHAR ucAction; + UCHAR ucEncoderMode; + // =0: DP encoder + // =1: LVDS encoder + // =2: DVI encoder + // =3: HDMI encoder + // =4: SDVO encoder + // =5: DP audio + UCHAR ucLaneNum; // how many lanes to enable + UCHAR ucBitPerColor; // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP + UCHAR ucReserved; +}DIG_ENCODER_CONTROL_PARAMETERS_V3; + + +// define ucBitPerColor: +#define PANEL_BPC_UNDEFINE 0x00 +#define PANEL_6BIT_PER_COLOR 0x01 +#define PANEL_8BIT_PER_COLOR 0x02 +#define PANEL_10BIT_PER_COLOR 0x03 +#define PANEL_12BIT_PER_COLOR 0x04 +#define PANEL_16BIT_PER_COLOR 0x05 + /****************************************************************************/ -/* Structures used by UNIPHYTransmitterControlTable */ -/* LVTMATransmitterControlTable */ -/* DVOOutputControlTable */ +// Structures used by UNIPHYTransmitterControlTable +// LVTMATransmitterControlTable +// DVOOutputControlTable /****************************************************************************/ -typedef struct _ATOM_DP_VS_MODE { +typedef struct _ATOM_DP_VS_MODE +{ UCHAR ucLaneSel; UCHAR ucLaneSet; -} ATOM_DP_VS_MODE; +}ATOM_DP_VS_MODE; -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS { - union { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - USHORT usInitInfo; /* when init uniphy,lower 8bit is used for connector type defined in objectid.h */ - ATOM_DP_VS_MODE asMode; /* DP Voltage swing mode */ +typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS +{ + union + { + USHORT usPixelClock; // in 10KHz; for bios convenient + USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h + ATOM_DP_VS_MODE asMode; // DP Voltage swing mode }; UCHAR ucConfig; - /* [0]=0: 4 lane Link, */ - /* =1: 8 lane Link ( Dual Links TMDS ) */ - /* [1]=0: InCoherent mode */ - /* =1: Coherent Mode */ - /* [2] Link Select: */ - /* =0: PHY linkA if bfLane<3 */ - /* =1: PHY linkB if bfLanes<3 */ - /* =0: PHY linkA+B if bfLanes=3 */ - /* [5:4]PCIE lane Sel */ - /* =0: lane 0~3 or 0~7 */ - /* =1: lane 4~7 */ - /* =2: lane 8~11 or 8~15 */ - /* =3: lane 12~15 */ - UCHAR ucAction; /* =0: turn off encoder */ - /* =1: turn on encoder */ + // [0]=0: 4 lane Link, + // =1: 8 lane Link ( Dual Links TMDS ) + // [1]=0: InCoherent mode + // =1: Coherent Mode + // [2] Link Select: + // =0: PHY linkA if bfLane<3 + // =1: PHY linkB if bfLanes<3 + // =0: PHY linkA+B if bfLanes=3 + // [5:4]PCIE lane Sel + // =0: lane 0~3 or 0~7 + // =1: lane 4~7 + // =2: lane 8~11 or 8~15 + // =3: lane 12~15 + UCHAR ucAction; // =0: turn off encoder + // =1: turn on encoder UCHAR ucReserved[4]; -} DIG_TRANSMITTER_CONTROL_PARAMETERS; +}DIG_TRANSMITTER_CONTROL_PARAMETERS; #define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION DIG_TRANSMITTER_CONTROL_PARAMETERS -/* ucInitInfo */ +//ucInitInfo #define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK 0x00ff -/* ucConfig */ +//ucConfig #define ATOM_TRANSMITTER_CONFIG_8LANE_LINK 0x01 #define ATOM_TRANSMITTER_CONFIG_COHERENT 0x02 #define ATOM_TRANSMITTER_CONFIG_LINK_SEL_MASK 0x04 @@ -645,9 +768,9 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS { #define ATOM_TRANSMITTER_CONFIG_LINKA_B 0x00 #define ATOM_TRANSMITTER_CONFIG_LINKB_A 0x04 -#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK 0x08 /* only used when ATOM_TRANSMITTER_ACTION_ENABLE */ -#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER 0x00 /* only used when ATOM_TRANSMITTER_ACTION_ENABLE */ -#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER 0x08 /* only used when ATOM_TRANSMITTER_ACTION_ENABLE */ +#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE +#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER 0x00 // only used when ATOM_TRANSMITTER_ACTION_ENABLE +#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE #define ATOM_TRANSMITTER_CONFIG_CLKSRC_MASK 0x30 #define ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL 0x00 @@ -661,7 +784,7 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS { #define ATOM_TRANSMITTER_CONFIG_LANE_8_15 0x80 #define ATOM_TRANSMITTER_CONFIG_LANE_12_15 0xc0 -/* ucAction */ +//ucAction #define ATOM_TRANSMITTER_ACTION_DISABLE 0 #define ATOM_TRANSMITTER_ACTION_ENABLE 1 #define ATOM_TRANSMITTER_ACTION_LCD_BLOFF 2 @@ -674,89 +797,164 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS { #define ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT 9 #define ATOM_TRANSMITTER_ACTION_SETUP 10 #define ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH 11 +#define ATOM_TRANSMITTER_ACTION_POWER_ON 12 +#define ATOM_TRANSMITTER_ACTION_POWER_OFF 13 -/* Following are used for DigTransmitterControlTable ver1.2 */ -typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2 { +// Following are used for DigTransmitterControlTable ver1.2 +typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2 +{ #if ATOM_BIG_ENDIAN - UCHAR ucTransmitterSel:2; /* bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) */ - /* =1 Dig Transmitter 2 ( Uniphy CD ) */ - /* =2 Dig Transmitter 3 ( Uniphy EF ) */ + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) UCHAR ucReserved:1; - UCHAR fDPConnector:1; /* bit4=0: DP connector =1: None DP connector */ - UCHAR ucEncoderSel:1; /* bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) */ - UCHAR ucLinkSel:1; /* bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E */ - /* =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F */ + UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR fCoherentMode:1; /* bit1=1: Coherent Mode ( for DVI/HDMI mode ) */ - UCHAR fDualLinkConnector:1; /* bit0=1: Dual Link DVI connector */ + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector #else - UCHAR fDualLinkConnector:1; /* bit0=1: Dual Link DVI connector */ - UCHAR fCoherentMode:1; /* bit1=1: Coherent Mode ( for DVI/HDMI mode ) */ - UCHAR ucLinkSel:1; /* bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E */ - /* =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F */ - UCHAR ucEncoderSel:1; /* bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) */ - UCHAR fDPConnector:1; /* bit4=0: DP connector =1: None DP connector */ + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) + UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector UCHAR ucReserved:1; - UCHAR ucTransmitterSel:2; /* bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) */ - /* =1 Dig Transmitter 2 ( Uniphy CD ) */ - /* =2 Dig Transmitter 3 ( Uniphy EF ) */ + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) #endif -} ATOM_DIG_TRANSMITTER_CONFIG_V2; +}ATOM_DIG_TRANSMITTER_CONFIG_V2; -/* ucConfig */ -/* Bit0 */ +//ucConfig +//Bit0 #define ATOM_TRANSMITTER_CONFIG_V2_DUAL_LINK_CONNECTOR 0x01 -/* Bit1 */ +//Bit1 #define ATOM_TRANSMITTER_CONFIG_V2_COHERENT 0x02 -/* Bit2 */ +//Bit2 #define ATOM_TRANSMITTER_CONFIG_V2_LINK_SEL_MASK 0x04 #define ATOM_TRANSMITTER_CONFIG_V2_LINKA 0x00 #define ATOM_TRANSMITTER_CONFIG_V2_LINKB 0x04 -/* Bit3 */ +// Bit3 #define ATOM_TRANSMITTER_CONFIG_V2_ENCODER_SEL_MASK 0x08 -#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER 0x00 /* only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP */ -#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER 0x08 /* only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP */ +#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER 0x00 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP +#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER 0x08 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP -/* Bit4 */ +// Bit4 #define ATOM_TRASMITTER_CONFIG_V2_DP_CONNECTOR 0x10 -/* Bit7:6 */ +// Bit7:6 #define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER_SEL_MASK 0xC0 -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1 0x00 /* AB */ -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2 0x40 /* CD */ -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3 0x80 /* EF */ +#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1 0x00 //AB +#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2 0x40 //CD +#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3 0x80 //EF -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 { - union { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - USHORT usInitInfo; /* when init uniphy,lower 8bit is used for connector type defined in objectid.h */ - ATOM_DP_VS_MODE asMode; /* DP Voltage swing mode */ +typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 +{ + union + { + USHORT usPixelClock; // in 10KHz; for bios convenient + USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h + ATOM_DP_VS_MODE asMode; // DP Voltage swing mode }; ATOM_DIG_TRANSMITTER_CONFIG_V2 acConfig; - UCHAR ucAction; /* define as ATOM_TRANSMITER_ACTION_XXX */ + UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX UCHAR ucReserved[4]; -} DIG_TRANSMITTER_CONTROL_PARAMETERS_V2; +}DIG_TRANSMITTER_CONTROL_PARAMETERS_V2; -/****************************************************************************/ -/* Structures used by DAC1OuputControlTable */ -/* DAC2OuputControlTable */ -/* LVTMAOutputControlTable (Before DEC30) */ -/* TMDSAOutputControlTable (Before DEC30) */ -/****************************************************************************/ -typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS { - UCHAR ucAction; /* Possible input:ATOM_ENABLE||ATOMDISABLE */ - /* When the display is LCD, in addition to above: */ - /* ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START|| */ - /* ATOM_LCD_SELFTEST_STOP */ +typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V3 +{ +#if ATOM_BIG_ENDIAN + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) + UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2 + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector +#else + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F + UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2 + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) +#endif +}ATOM_DIG_TRANSMITTER_CONFIG_V3; - UCHAR aucPadding[3]; /* padding to DWORD aligned */ -} DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS; +typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 +{ + union + { + USHORT usPixelClock; // in 10KHz; for bios convenient + USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h + ATOM_DP_VS_MODE asMode; // DP Voltage swing mode + }; + ATOM_DIG_TRANSMITTER_CONFIG_V3 acConfig; + UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX + UCHAR ucLaneNum; + UCHAR ucReserved[3]; +}DIG_TRANSMITTER_CONTROL_PARAMETERS_V3; + +//ucConfig +//Bit0 +#define ATOM_TRANSMITTER_CONFIG_V3_DUAL_LINK_CONNECTOR 0x01 + +//Bit1 +#define ATOM_TRANSMITTER_CONFIG_V3_COHERENT 0x02 + +//Bit2 +#define ATOM_TRANSMITTER_CONFIG_V3_LINK_SEL_MASK 0x04 +#define ATOM_TRANSMITTER_CONFIG_V3_LINKA 0x00 +#define ATOM_TRANSMITTER_CONFIG_V3_LINKB 0x04 + +// Bit3 +#define ATOM_TRANSMITTER_CONFIG_V3_ENCODER_SEL_MASK 0x08 +#define ATOM_TRANSMITTER_CONFIG_V3_DIG1_ENCODER 0x00 +#define ATOM_TRANSMITTER_CONFIG_V3_DIG2_ENCODER 0x08 + +// Bit5:4 +#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SEL_MASK 0x30 +#define ATOM_TRASMITTER_CONFIG_V3_P1PLL 0x00 +#define ATOM_TRASMITTER_CONFIG_V3_P2PLL 0x10 +#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SRC_EXT 0x20 + +// Bit7:6 +#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER_SEL_MASK 0xC0 +#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER1 0x00 //AB +#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2 0x40 //CD +#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3 0x80 //EF + +/****************************************************************************/ +// Structures used by DAC1OuputControlTable +// DAC2OuputControlTable +// LVTMAOutputControlTable (Before DEC30) +// TMDSAOutputControlTable (Before DEC30) +/****************************************************************************/ +typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS +{ + UCHAR ucAction; // Possible input:ATOM_ENABLE||ATOMDISABLE + // When the display is LCD, in addition to above: + // ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START|| + // ATOM_LCD_SELFTEST_STOP + + UCHAR aucPadding[3]; // padding to DWORD aligned +}DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS; #define DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS + #define CRT1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS #define CRT1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION @@ -783,352 +981,503 @@ typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS { #define DVO_OUTPUT_CONTROL_PARAMETERS_V3 DIG_TRANSMITTER_CONTROL_PARAMETERS /****************************************************************************/ -/* Structures used by BlankCRTCTable */ +// Structures used by BlankCRTCTable /****************************************************************************/ -typedef struct _BLANK_CRTC_PARAMETERS { - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ - UCHAR ucBlanking; /* ATOM_BLANKING or ATOM_BLANKINGOFF */ +typedef struct _BLANK_CRTC_PARAMETERS +{ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 + UCHAR ucBlanking; // ATOM_BLANKING or ATOM_BLANKINGOFF USHORT usBlackColorRCr; USHORT usBlackColorGY; USHORT usBlackColorBCb; -} BLANK_CRTC_PARAMETERS; +}BLANK_CRTC_PARAMETERS; #define BLANK_CRTC_PS_ALLOCATION BLANK_CRTC_PARAMETERS /****************************************************************************/ -/* Structures used by EnableCRTCTable */ -/* EnableCRTCMemReqTable */ -/* UpdateCRTC_DoubleBufferRegistersTable */ -/****************************************************************************/ -typedef struct _ENABLE_CRTC_PARAMETERS { - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ +// Structures used by EnableCRTCTable +// EnableCRTCMemReqTable +// UpdateCRTC_DoubleBufferRegistersTable +/****************************************************************************/ +typedef struct _ENABLE_CRTC_PARAMETERS +{ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE UCHAR ucPadding[2]; -} ENABLE_CRTC_PARAMETERS; +}ENABLE_CRTC_PARAMETERS; #define ENABLE_CRTC_PS_ALLOCATION ENABLE_CRTC_PARAMETERS /****************************************************************************/ -/* Structures used by SetCRTC_OverScanTable */ +// Structures used by SetCRTC_OverScanTable /****************************************************************************/ -typedef struct _SET_CRTC_OVERSCAN_PARAMETERS { - USHORT usOverscanRight; /* right */ - USHORT usOverscanLeft; /* left */ - USHORT usOverscanBottom; /* bottom */ - USHORT usOverscanTop; /* top */ - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ +typedef struct _SET_CRTC_OVERSCAN_PARAMETERS +{ + USHORT usOverscanRight; // right + USHORT usOverscanLeft; // left + USHORT usOverscanBottom; // bottom + USHORT usOverscanTop; // top + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 UCHAR ucPadding[3]; -} SET_CRTC_OVERSCAN_PARAMETERS; +}SET_CRTC_OVERSCAN_PARAMETERS; #define SET_CRTC_OVERSCAN_PS_ALLOCATION SET_CRTC_OVERSCAN_PARAMETERS /****************************************************************************/ -/* Structures used by SetCRTC_ReplicationTable */ +// Structures used by SetCRTC_ReplicationTable /****************************************************************************/ -typedef struct _SET_CRTC_REPLICATION_PARAMETERS { - UCHAR ucH_Replication; /* horizontal replication */ - UCHAR ucV_Replication; /* vertical replication */ - UCHAR usCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ +typedef struct _SET_CRTC_REPLICATION_PARAMETERS +{ + UCHAR ucH_Replication; // horizontal replication + UCHAR ucV_Replication; // vertical replication + UCHAR usCRTC; // ATOM_CRTC1 or ATOM_CRTC2 UCHAR ucPadding; -} SET_CRTC_REPLICATION_PARAMETERS; +}SET_CRTC_REPLICATION_PARAMETERS; #define SET_CRTC_REPLICATION_PS_ALLOCATION SET_CRTC_REPLICATION_PARAMETERS /****************************************************************************/ -/* Structures used by SelectCRTC_SourceTable */ +// Structures used by SelectCRTC_SourceTable /****************************************************************************/ -typedef struct _SELECT_CRTC_SOURCE_PARAMETERS { - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ - UCHAR ucDevice; /* ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|.... */ +typedef struct _SELECT_CRTC_SOURCE_PARAMETERS +{ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 + UCHAR ucDevice; // ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|.... UCHAR ucPadding[2]; -} SELECT_CRTC_SOURCE_PARAMETERS; +}SELECT_CRTC_SOURCE_PARAMETERS; #define SELECT_CRTC_SOURCE_PS_ALLOCATION SELECT_CRTC_SOURCE_PARAMETERS -typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2 { - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ - UCHAR ucEncoderID; /* DAC1/DAC2/TVOUT/DIG1/DIG2/DVO */ - UCHAR ucEncodeMode; /* Encoding mode, only valid when using DIG1/DIG2/DVO */ +typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2 +{ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 + UCHAR ucEncoderID; // DAC1/DAC2/TVOUT/DIG1/DIG2/DVO + UCHAR ucEncodeMode; // Encoding mode, only valid when using DIG1/DIG2/DVO UCHAR ucPadding; -} SELECT_CRTC_SOURCE_PARAMETERS_V2; +}SELECT_CRTC_SOURCE_PARAMETERS_V2; -/* ucEncoderID */ -/* #define ASIC_INT_DAC1_ENCODER_ID 0x00 */ -/* #define ASIC_INT_TV_ENCODER_ID 0x02 */ -/* #define ASIC_INT_DIG1_ENCODER_ID 0x03 */ -/* #define ASIC_INT_DAC2_ENCODER_ID 0x04 */ -/* #define ASIC_EXT_TV_ENCODER_ID 0x06 */ -/* #define ASIC_INT_DVO_ENCODER_ID 0x07 */ -/* #define ASIC_INT_DIG2_ENCODER_ID 0x09 */ -/* #define ASIC_EXT_DIG_ENCODER_ID 0x05 */ +//ucEncoderID +//#define ASIC_INT_DAC1_ENCODER_ID 0x00 +//#define ASIC_INT_TV_ENCODER_ID 0x02 +//#define ASIC_INT_DIG1_ENCODER_ID 0x03 +//#define ASIC_INT_DAC2_ENCODER_ID 0x04 +//#define ASIC_EXT_TV_ENCODER_ID 0x06 +//#define ASIC_INT_DVO_ENCODER_ID 0x07 +//#define ASIC_INT_DIG2_ENCODER_ID 0x09 +//#define ASIC_EXT_DIG_ENCODER_ID 0x05 -/* ucEncodeMode */ -/* #define ATOM_ENCODER_MODE_DP 0 */ -/* #define ATOM_ENCODER_MODE_LVDS 1 */ -/* #define ATOM_ENCODER_MODE_DVI 2 */ -/* #define ATOM_ENCODER_MODE_HDMI 3 */ -/* #define ATOM_ENCODER_MODE_SDVO 4 */ -/* #define ATOM_ENCODER_MODE_TV 13 */ -/* #define ATOM_ENCODER_MODE_CV 14 */ -/* #define ATOM_ENCODER_MODE_CRT 15 */ +//ucEncodeMode +//#define ATOM_ENCODER_MODE_DP 0 +//#define ATOM_ENCODER_MODE_LVDS 1 +//#define ATOM_ENCODER_MODE_DVI 2 +//#define ATOM_ENCODER_MODE_HDMI 3 +//#define ATOM_ENCODER_MODE_SDVO 4 +//#define ATOM_ENCODER_MODE_TV 13 +//#define ATOM_ENCODER_MODE_CV 14 +//#define ATOM_ENCODER_MODE_CRT 15 -/****************************************************************************/ -/* Structures used by SetPixelClockTable */ -/* GetPixelClockTable */ -/****************************************************************************/ -/* Major revision=1., Minor revision=1 */ -typedef struct _PIXEL_CLOCK_PARAMETERS { - USHORT usPixelClock; /* in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */ - /* 0 means disable PPLL */ - USHORT usRefDiv; /* Reference divider */ - USHORT usFbDiv; /* feedback divider */ - UCHAR ucPostDiv; /* post divider */ - UCHAR ucFracFbDiv; /* fractional feedback divider */ - UCHAR ucPpll; /* ATOM_PPLL1 or ATOM_PPL2 */ - UCHAR ucRefDivSrc; /* ATOM_PJITTER or ATO_NONPJITTER */ - UCHAR ucCRTC; /* Which CRTC uses this Ppll */ +/****************************************************************************/ +// Structures used by SetPixelClockTable +// GetPixelClockTable +/****************************************************************************/ +//Major revision=1., Minor revision=1 +typedef struct _PIXEL_CLOCK_PARAMETERS +{ + USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) + // 0 means disable PPLL + USHORT usRefDiv; // Reference divider + USHORT usFbDiv; // feedback divider + UCHAR ucPostDiv; // post divider + UCHAR ucFracFbDiv; // fractional feedback divider + UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 + UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER + UCHAR ucCRTC; // Which CRTC uses this Ppll UCHAR ucPadding; -} PIXEL_CLOCK_PARAMETERS; +}PIXEL_CLOCK_PARAMETERS; -/* Major revision=1., Minor revision=2, add ucMiscIfno */ -/* ucMiscInfo: */ +//Major revision=1., Minor revision=2, add ucMiscIfno +//ucMiscInfo: #define MISC_FORCE_REPROG_PIXEL_CLOCK 0x1 #define MISC_DEVICE_INDEX_MASK 0xF0 #define MISC_DEVICE_INDEX_SHIFT 4 -typedef struct _PIXEL_CLOCK_PARAMETERS_V2 { - USHORT usPixelClock; /* in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */ - /* 0 means disable PPLL */ - USHORT usRefDiv; /* Reference divider */ - USHORT usFbDiv; /* feedback divider */ - UCHAR ucPostDiv; /* post divider */ - UCHAR ucFracFbDiv; /* fractional feedback divider */ - UCHAR ucPpll; /* ATOM_PPLL1 or ATOM_PPL2 */ - UCHAR ucRefDivSrc; /* ATOM_PJITTER or ATO_NONPJITTER */ - UCHAR ucCRTC; /* Which CRTC uses this Ppll */ - UCHAR ucMiscInfo; /* Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog */ -} PIXEL_CLOCK_PARAMETERS_V2; +typedef struct _PIXEL_CLOCK_PARAMETERS_V2 +{ + USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) + // 0 means disable PPLL + USHORT usRefDiv; // Reference divider + USHORT usFbDiv; // feedback divider + UCHAR ucPostDiv; // post divider + UCHAR ucFracFbDiv; // fractional feedback divider + UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 + UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER + UCHAR ucCRTC; // Which CRTC uses this Ppll + UCHAR ucMiscInfo; // Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog +}PIXEL_CLOCK_PARAMETERS_V2; -/* Major revision=1., Minor revision=3, structure/definition change */ -/* ucEncoderMode: */ -/* ATOM_ENCODER_MODE_DP */ -/* ATOM_ENOCDER_MODE_LVDS */ -/* ATOM_ENOCDER_MODE_DVI */ -/* ATOM_ENOCDER_MODE_HDMI */ -/* ATOM_ENOCDER_MODE_SDVO */ -/* ATOM_ENCODER_MODE_TV 13 */ -/* ATOM_ENCODER_MODE_CV 14 */ -/* ATOM_ENCODER_MODE_CRT 15 */ +//Major revision=1., Minor revision=3, structure/definition change +//ucEncoderMode: +//ATOM_ENCODER_MODE_DP +//ATOM_ENOCDER_MODE_LVDS +//ATOM_ENOCDER_MODE_DVI +//ATOM_ENOCDER_MODE_HDMI +//ATOM_ENOCDER_MODE_SDVO +//ATOM_ENCODER_MODE_TV 13 +//ATOM_ENCODER_MODE_CV 14 +//ATOM_ENCODER_MODE_CRT 15 -/* ucDVOConfig */ -/* #define DVO_ENCODER_CONFIG_RATE_SEL 0x01 */ -/* #define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 */ -/* #define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 */ -/* #define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c */ -/* #define DVO_ENCODER_CONFIG_LOW12BIT 0x00 */ -/* #define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 */ -/* #define DVO_ENCODER_CONFIG_24BIT 0x08 */ +//ucDVOConfig +//#define DVO_ENCODER_CONFIG_RATE_SEL 0x01 +//#define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 +//#define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 +//#define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c +//#define DVO_ENCODER_CONFIG_LOW12BIT 0x00 +//#define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 +//#define DVO_ENCODER_CONFIG_24BIT 0x08 -/* ucMiscInfo: also changed, see below */ +//ucMiscInfo: also changed, see below #define PIXEL_CLOCK_MISC_FORCE_PROG_PPLL 0x01 #define PIXEL_CLOCK_MISC_VGA_MODE 0x02 #define PIXEL_CLOCK_MISC_CRTC_SEL_MASK 0x04 #define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1 0x00 #define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2 0x04 #define PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK 0x08 +#define PIXEL_CLOCK_MISC_REF_DIV_SRC 0x10 +// V1.4 for RoadRunner +#define PIXEL_CLOCK_V4_MISC_SS_ENABLE 0x10 +#define PIXEL_CLOCK_V4_MISC_COHERENT_MODE 0x20 -typedef struct _PIXEL_CLOCK_PARAMETERS_V3 { - USHORT usPixelClock; /* in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) */ - /* 0 means disable PPLL. For VGA PPLL,make sure this value is not 0. */ - USHORT usRefDiv; /* Reference divider */ - USHORT usFbDiv; /* feedback divider */ - UCHAR ucPostDiv; /* post divider */ - UCHAR ucFracFbDiv; /* fractional feedback divider */ - UCHAR ucPpll; /* ATOM_PPLL1 or ATOM_PPL2 */ - UCHAR ucTransmitterId; /* graphic encoder id defined in objectId.h */ - union { - UCHAR ucEncoderMode; /* encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/ */ - UCHAR ucDVOConfig; /* when use DVO, need to know SDR/DDR, 12bit or 24bit */ +typedef struct _PIXEL_CLOCK_PARAMETERS_V3 +{ + USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) + // 0 means disable PPLL. For VGA PPLL,make sure this value is not 0. + USHORT usRefDiv; // Reference divider + USHORT usFbDiv; // feedback divider + UCHAR ucPostDiv; // post divider + UCHAR ucFracFbDiv; // fractional feedback divider + UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 + UCHAR ucTransmitterId; // graphic encoder id defined in objectId.h + union + { + UCHAR ucEncoderMode; // encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/ + UCHAR ucDVOConfig; // when use DVO, need to know SDR/DDR, 12bit or 24bit }; - UCHAR ucMiscInfo; /* bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel */ - /* bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source */ -} PIXEL_CLOCK_PARAMETERS_V3; + UCHAR ucMiscInfo; // bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel + // bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source + // bit[4]=0:use XTALIN as the source of reference divider,=1 use the pre-defined clock as the source of reference divider +}PIXEL_CLOCK_PARAMETERS_V3; #define PIXEL_CLOCK_PARAMETERS_LAST PIXEL_CLOCK_PARAMETERS_V2 #define GET_PIXEL_CLOCK_PS_ALLOCATION PIXEL_CLOCK_PARAMETERS_LAST +typedef struct _PIXEL_CLOCK_PARAMETERS_V5 +{ + UCHAR ucCRTC; // ATOM_CRTC1~6, indicate the CRTC controller to + // drive the pixel clock. not used for DCPLL case. + union{ + UCHAR ucReserved; + UCHAR ucFracFbDiv; // [gphan] temporary to prevent build problem. remove it after driver code is changed. + }; + USHORT usPixelClock; // target the pixel clock to drive the CRTC timing + // 0 means disable PPLL/DCPLL. + USHORT usFbDiv; // feedback divider integer part. + UCHAR ucPostDiv; // post divider. + UCHAR ucRefDiv; // Reference divider + UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL + UCHAR ucTransmitterID; // ASIC encoder id defined in objectId.h, + // indicate which graphic encoder will be used. + UCHAR ucEncoderMode; // Encoder mode: + UCHAR ucMiscInfo; // bit[0]= Force program PPLL + // bit[1]= when VGA timing is used. + // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp + // bit[4]= RefClock source for PPLL. + // =0: XTLAIN( default mode ) + // =1: other external clock source, which is pre-defined + // by VBIOS depend on the feature required. + // bit[7:5]: reserved. + ULONG ulFbDivDecFrac; // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 ) + +}PIXEL_CLOCK_PARAMETERS_V5; + +#define PIXEL_CLOCK_V5_MISC_FORCE_PROG_PPLL 0x01 +#define PIXEL_CLOCK_V5_MISC_VGA_MODE 0x02 +#define PIXEL_CLOCK_V5_MISC_HDMI_BPP_MASK 0x0c +#define PIXEL_CLOCK_V5_MISC_HDMI_24BPP 0x00 +#define PIXEL_CLOCK_V5_MISC_HDMI_30BPP 0x04 +#define PIXEL_CLOCK_V5_MISC_HDMI_32BPP 0x08 +#define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC 0x10 + +typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2 +{ + PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput; +}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2; + +typedef struct _GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2 +{ + UCHAR ucStatus; + UCHAR ucRefDivSrc; // =1: reference clock source from XTALIN, =0: source from PCIE ref clock + UCHAR ucReserved[2]; +}GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2; + +typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3 +{ + PIXEL_CLOCK_PARAMETERS_V5 sDispClkInput; +}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3; + /****************************************************************************/ -/* Structures used by AdjustDisplayPllTable */ +// Structures used by AdjustDisplayPllTable /****************************************************************************/ -typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS { +typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS +{ USHORT usPixelClock; UCHAR ucTransmitterID; UCHAR ucEncodeMode; - union { - UCHAR ucDVOConfig; /* if DVO, need passing link rate and output 12bitlow or 24bit */ - UCHAR ucConfig; /* if none DVO, not defined yet */ + union + { + UCHAR ucDVOConfig; //if DVO, need passing link rate and output 12bitlow or 24bit + UCHAR ucConfig; //if none DVO, not defined yet }; UCHAR ucReserved[3]; -} ADJUST_DISPLAY_PLL_PARAMETERS; +}ADJUST_DISPLAY_PLL_PARAMETERS; #define ADJUST_DISPLAY_CONFIG_SS_ENABLE 0x10 - #define ADJUST_DISPLAY_PLL_PS_ALLOCATION ADJUST_DISPLAY_PLL_PARAMETERS +typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 +{ + USHORT usPixelClock; // target pixel clock + UCHAR ucTransmitterID; // transmitter id defined in objectid.h + UCHAR ucEncodeMode; // encoder mode: CRT, LVDS, DP, TMDS or HDMI + UCHAR ucDispPllConfig; // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX + UCHAR ucReserved[3]; +}ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3; + +// usDispPllConfig v1.2 for RoadRunner +#define DISPPLL_CONFIG_DVO_RATE_SEL 0x0001 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_DDR_SPEED 0x0000 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_SDR_SPEED 0x0001 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_OUTPUT_SEL 0x000c // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_LOW12BIT 0x0000 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_UPPER12BIT 0x0004 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_DVO_24BIT 0x0008 // need only when ucTransmitterID = DVO +#define DISPPLL_CONFIG_SS_ENABLE 0x0010 // Only used when ucEncoderMode = DP or LVDS +#define DISPPLL_CONFIG_COHERENT_MODE 0x0020 // Only used when ucEncoderMode = TMDS or HDMI +#define DISPPLL_CONFIG_DUAL_LINK 0x0040 // Only used when ucEncoderMode = TMDS or LVDS + + +typedef struct _ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3 +{ + ULONG ulDispPllFreq; // return display PPLL freq which is used to generate the pixclock, and related idclk, symclk etc + UCHAR ucRefDiv; // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider and post_div ( if it is not given ) + UCHAR ucPostDiv; // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider + UCHAR ucReserved[2]; +}ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3; + +typedef struct _ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 +{ + union + { + ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 sInput; + ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3 sOutput; + }; +} ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3; + /****************************************************************************/ -/* Structures used by EnableYUVTable */ +// Structures used by EnableYUVTable /****************************************************************************/ -typedef struct _ENABLE_YUV_PARAMETERS { - UCHAR ucEnable; /* ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB) */ - UCHAR ucCRTC; /* Which CRTC needs this YUV or RGB format */ +typedef struct _ENABLE_YUV_PARAMETERS +{ + UCHAR ucEnable; // ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB) + UCHAR ucCRTC; // Which CRTC needs this YUV or RGB format UCHAR ucPadding[2]; -} ENABLE_YUV_PARAMETERS; +}ENABLE_YUV_PARAMETERS; #define ENABLE_YUV_PS_ALLOCATION ENABLE_YUV_PARAMETERS /****************************************************************************/ -/* Structures used by GetMemoryClockTable */ +// Structures used by GetMemoryClockTable /****************************************************************************/ -typedef struct _GET_MEMORY_CLOCK_PARAMETERS { - ULONG ulReturnMemoryClock; /* current memory speed in 10KHz unit */ +typedef struct _GET_MEMORY_CLOCK_PARAMETERS +{ + ULONG ulReturnMemoryClock; // current memory speed in 10KHz unit } GET_MEMORY_CLOCK_PARAMETERS; #define GET_MEMORY_CLOCK_PS_ALLOCATION GET_MEMORY_CLOCK_PARAMETERS /****************************************************************************/ -/* Structures used by GetEngineClockTable */ +// Structures used by GetEngineClockTable /****************************************************************************/ -typedef struct _GET_ENGINE_CLOCK_PARAMETERS { - ULONG ulReturnEngineClock; /* current engine speed in 10KHz unit */ +typedef struct _GET_ENGINE_CLOCK_PARAMETERS +{ + ULONG ulReturnEngineClock; // current engine speed in 10KHz unit } GET_ENGINE_CLOCK_PARAMETERS; #define GET_ENGINE_CLOCK_PS_ALLOCATION GET_ENGINE_CLOCK_PARAMETERS /****************************************************************************/ -/* Following Structures and constant may be obsolete */ +// Following Structures and constant may be obsolete /****************************************************************************/ -/* Maxium 8 bytes,the data read in will be placed in the parameter space. */ -/* Read operaion successeful when the paramter space is non-zero, otherwise read operation failed */ -typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS { - USHORT usPrescale; /* Ratio between Engine clock and I2C clock */ - USHORT usVRAMAddress; /* Adress in Frame Buffer where to pace raw EDID */ - USHORT usStatus; /* When use output: lower byte EDID checksum, high byte hardware status */ - /* WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte */ - UCHAR ucSlaveAddr; /* Read from which slave */ - UCHAR ucLineNumber; /* Read from which HW assisted line */ -} READ_EDID_FROM_HW_I2C_DATA_PARAMETERS; +//Maxium 8 bytes,the data read in will be placed in the parameter space. +//Read operaion successeful when the paramter space is non-zero, otherwise read operation failed +typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS +{ + USHORT usPrescale; //Ratio between Engine clock and I2C clock + USHORT usVRAMAddress; //Adress in Frame Buffer where to pace raw EDID + USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status + //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte + UCHAR ucSlaveAddr; //Read from which slave + UCHAR ucLineNumber; //Read from which HW assisted line +}READ_EDID_FROM_HW_I2C_DATA_PARAMETERS; #define READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION READ_EDID_FROM_HW_I2C_DATA_PARAMETERS + #define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSDATABYTE 0 #define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSTWODATABYTES 1 #define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_PSOFFSET_IDDATABLOCK 2 #define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_IDOFFSET_PLUS_IDDATABLOCK 3 #define ATOM_WRITE_I2C_FORMAT_IDCOUNTER_IDOFFSET_IDDATABLOCK 4 -typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS { - USHORT usPrescale; /* Ratio between Engine clock and I2C clock */ - USHORT usByteOffset; /* Write to which byte */ - /* Upper portion of usByteOffset is Format of data */ - /* 1bytePS+offsetPS */ - /* 2bytesPS+offsetPS */ - /* blockID+offsetPS */ - /* blockID+offsetID */ - /* blockID+counterID+offsetID */ - UCHAR ucData; /* PS data1 */ - UCHAR ucStatus; /* Status byte 1=success, 2=failure, Also is used as PS data2 */ - UCHAR ucSlaveAddr; /* Write to which slave */ - UCHAR ucLineNumber; /* Write from which HW assisted line */ -} WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS; +typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS +{ + USHORT usPrescale; //Ratio between Engine clock and I2C clock + USHORT usByteOffset; //Write to which byte + //Upper portion of usByteOffset is Format of data + //1bytePS+offsetPS + //2bytesPS+offsetPS + //blockID+offsetPS + //blockID+offsetID + //blockID+counterID+offsetID + UCHAR ucData; //PS data1 + UCHAR ucStatus; //Status byte 1=success, 2=failure, Also is used as PS data2 + UCHAR ucSlaveAddr; //Write to which slave + UCHAR ucLineNumber; //Write from which HW assisted line +}WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS; #define WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS -typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS { - USHORT usPrescale; /* Ratio between Engine clock and I2C clock */ - UCHAR ucSlaveAddr; /* Write to which slave */ - UCHAR ucLineNumber; /* Write from which HW assisted line */ -} SET_UP_HW_I2C_DATA_PARAMETERS; +typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS +{ + USHORT usPrescale; //Ratio between Engine clock and I2C clock + UCHAR ucSlaveAddr; //Write to which slave + UCHAR ucLineNumber; //Write from which HW assisted line +}SET_UP_HW_I2C_DATA_PARAMETERS; + /**************************************************************************/ #define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS /****************************************************************************/ -/* Structures used by PowerConnectorDetectionTable */ +// Structures used by PowerConnectorDetectionTable /****************************************************************************/ -typedef struct _POWER_CONNECTOR_DETECTION_PARAMETERS { - UCHAR ucPowerConnectorStatus; /* Used for return value 0: detected, 1:not detected */ +typedef struct _POWER_CONNECTOR_DETECTION_PARAMETERS +{ + UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected UCHAR ucPwrBehaviorId; - USHORT usPwrBudget; /* how much power currently boot to in unit of watt */ -} POWER_CONNECTOR_DETECTION_PARAMETERS; + USHORT usPwrBudget; //how much power currently boot to in unit of watt +}POWER_CONNECTOR_DETECTION_PARAMETERS; -typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION { - UCHAR ucPowerConnectorStatus; /* Used for return value 0: detected, 1:not detected */ +typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION +{ + UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected UCHAR ucReserved; - USHORT usPwrBudget; /* how much power currently boot to in unit of watt */ + USHORT usPwrBudget; //how much power currently boot to in unit of watt WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -} POWER_CONNECTOR_DETECTION_PS_ALLOCATION; +}POWER_CONNECTOR_DETECTION_PS_ALLOCATION; /****************************LVDS SS Command Table Definitions**********************/ /****************************************************************************/ -/* Structures used by EnableSpreadSpectrumOnPPLLTable */ +// Structures used by EnableSpreadSpectrumOnPPLLTable /****************************************************************************/ -typedef struct _ENABLE_LVDS_SS_PARAMETERS { +typedef struct _ENABLE_LVDS_SS_PARAMETERS +{ USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; /* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */ - UCHAR ucSpreadSpectrumStepSize_Delay; /* bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ + UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD + UCHAR ucSpreadSpectrumStepSize_Delay; //bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY + UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE UCHAR ucPadding[3]; -} ENABLE_LVDS_SS_PARAMETERS; +}ENABLE_LVDS_SS_PARAMETERS; -/* ucTableFormatRevision=1,ucTableContentRevision=2 */ -typedef struct _ENABLE_LVDS_SS_PARAMETERS_V2 { +//ucTableFormatRevision=1,ucTableContentRevision=2 +typedef struct _ENABLE_LVDS_SS_PARAMETERS_V2 +{ USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; /* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */ - UCHAR ucSpreadSpectrumStep; /* */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ + UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD + UCHAR ucSpreadSpectrumStep; // + UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE UCHAR ucSpreadSpectrumDelay; UCHAR ucSpreadSpectrumRange; UCHAR ucPadding; -} ENABLE_LVDS_SS_PARAMETERS_V2; +}ENABLE_LVDS_SS_PARAMETERS_V2; -/* This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS. */ -typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL { +//This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS. +typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL +{ USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; /* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */ - UCHAR ucSpreadSpectrumStep; /* */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ + UCHAR ucSpreadSpectrumType; // Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD + UCHAR ucSpreadSpectrumStep; // + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE UCHAR ucSpreadSpectrumDelay; UCHAR ucSpreadSpectrumRange; - UCHAR ucPpll; /* ATOM_PPLL1/ATOM_PPLL2 */ -} ENABLE_SPREAD_SPECTRUM_ON_PPLL; + UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2 +}ENABLE_SPREAD_SPECTRUM_ON_PPLL; + +typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 +{ + USHORT usSpreadSpectrumPercentage; + UCHAR ucSpreadSpectrumType; // Bit[0]: 0-Down Spread,1-Center Spread. + // Bit[1]: 1-Ext. 0-Int. + // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL + // Bits[7:4] reserved + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE + USHORT usSpreadSpectrumAmount; // Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8] + USHORT usSpreadSpectrumStep; // SS_STEP_SIZE_DSFRAC +}ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2; + +#define ATOM_PPLL_SS_TYPE_V2_DOWN_SPREAD 0x00 +#define ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD 0x01 +#define ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD 0x02 +#define ATOM_PPLL_SS_TYPE_V2_PPLL_SEL_MASK 0x0c +#define ATOM_PPLL_SS_TYPE_V2_P1PLL 0x00 +#define ATOM_PPLL_SS_TYPE_V2_P2PLL 0x04 +#define ATOM_PPLL_SS_TYPE_V2_DCPLL 0x08 +#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK 0x00FF +#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT 0 +#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK 0x0F00 +#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT 8 #define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL /**************************************************************************/ -typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION { +typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION +{ PIXEL_CLOCK_PARAMETERS sPCLKInput; - ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved; /* Caller doesn't need to init this portion */ -} SET_PIXEL_CLOCK_PS_ALLOCATION; + ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;//Caller doesn't need to init this portion +}SET_PIXEL_CLOCK_PS_ALLOCATION; #define ENABLE_VGA_RENDER_PS_ALLOCATION SET_PIXEL_CLOCK_PS_ALLOCATION /****************************************************************************/ -/* Structures used by ### */ +// Structures used by ### /****************************************************************************/ -typedef struct _MEMORY_TRAINING_PARAMETERS { - ULONG ulTargetMemoryClock; /* In 10Khz unit */ -} MEMORY_TRAINING_PARAMETERS; +typedef struct _MEMORY_TRAINING_PARAMETERS +{ + ULONG ulTargetMemoryClock; //In 10Khz unit +}MEMORY_TRAINING_PARAMETERS; #define MEMORY_TRAINING_PS_ALLOCATION MEMORY_TRAINING_PARAMETERS + /****************************LVDS and other encoder command table definitions **********************/ + +/****************************************************************************/ +// Structures used by LVDSEncoderControlTable (Before DCE30) +// LVTMAEncoderControlTable (Before DCE30) +// TMDSAEncoderControlTable (Before DCE30) /****************************************************************************/ -/* Structures used by LVDSEncoderControlTable (Before DCE30) */ -/* LVTMAEncoderControlTable (Before DCE30) */ -/* TMDSAEncoderControlTable (Before DCE30) */ -/****************************************************************************/ -typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucMisc; /* bit0=0: Enable single link */ - /* =1: Enable dual link */ - /* Bit1=0: 666RGB */ - /* =1: 888RGB */ - UCHAR ucAction; /* 0: turn off encoder */ - /* 1: setup and turn on encoder */ -} LVDS_ENCODER_CONTROL_PARAMETERS; +typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + UCHAR ucMisc; // bit0=0: Enable single link + // =1: Enable dual link + // Bit1=0: 666RGB + // =1: 888RGB + UCHAR ucAction; // 0: turn off encoder + // 1: setup and turn on encoder +}LVDS_ENCODER_CONTROL_PARAMETERS; #define LVDS_ENCODER_CONTROL_PS_ALLOCATION LVDS_ENCODER_CONTROL_PARAMETERS @@ -1138,35 +1487,37 @@ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS { #define TMDS2_ENCODER_CONTROL_PARAMETERS TMDS1_ENCODER_CONTROL_PARAMETERS #define TMDS2_ENCODER_CONTROL_PS_ALLOCATION TMDS2_ENCODER_CONTROL_PARAMETERS -/* ucTableFormatRevision=1,ucTableContentRevision=2 */ -typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx definitions below */ - UCHAR ucAction; /* 0: turn off encoder */ - /* 1: setup and turn on encoder */ - UCHAR ucTruncate; /* bit0=0: Disable truncate */ - /* =1: Enable truncate */ - /* bit4=0: 666RGB */ - /* =1: 888RGB */ - UCHAR ucSpatial; /* bit0=0: Disable spatial dithering */ - /* =1: Enable spatial dithering */ - /* bit4=0: 666RGB */ - /* =1: 888RGB */ - UCHAR ucTemporal; /* bit0=0: Disable temporal dithering */ - /* =1: Enable temporal dithering */ - /* bit4=0: 666RGB */ - /* =1: 888RGB */ - /* bit5=0: Gray level 2 */ - /* =1: Gray level 4 */ - UCHAR ucFRC; /* bit4=0: 25FRC_SEL pattern E */ - /* =1: 25FRC_SEL pattern F */ - /* bit6:5=0: 50FRC_SEL pattern A */ - /* =1: 50FRC_SEL pattern B */ - /* =2: 50FRC_SEL pattern C */ - /* =3: 50FRC_SEL pattern D */ - /* bit7=0: 75FRC_SEL pattern E */ - /* =1: 75FRC_SEL pattern F */ -} LVDS_ENCODER_CONTROL_PARAMETERS_V2; + +//ucTableFormatRevision=1,ucTableContentRevision=2 +typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + UCHAR ucMisc; // see PANEL_ENCODER_MISC_xx defintions below + UCHAR ucAction; // 0: turn off encoder + // 1: setup and turn on encoder + UCHAR ucTruncate; // bit0=0: Disable truncate + // =1: Enable truncate + // bit4=0: 666RGB + // =1: 888RGB + UCHAR ucSpatial; // bit0=0: Disable spatial dithering + // =1: Enable spatial dithering + // bit4=0: 666RGB + // =1: 888RGB + UCHAR ucTemporal; // bit0=0: Disable temporal dithering + // =1: Enable temporal dithering + // bit4=0: 666RGB + // =1: 888RGB + // bit5=0: Gray level 2 + // =1: Gray level 4 + UCHAR ucFRC; // bit4=0: 25FRC_SEL pattern E + // =1: 25FRC_SEL pattern F + // bit6:5=0: 50FRC_SEL pattern A + // =1: 50FRC_SEL pattern B + // =2: 50FRC_SEL pattern C + // =3: 50FRC_SEL pattern D + // bit7=0: 75FRC_SEL pattern E + // =1: 75FRC_SEL pattern F +}LVDS_ENCODER_CONTROL_PARAMETERS_V2; #define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 @@ -1186,37 +1537,41 @@ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { #define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS2_ENCODER_CONTROL_PARAMETERS_V3 /****************************************************************************/ -/* Structures used by ### */ +// Structures used by ### /****************************************************************************/ -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS { - UCHAR ucEnable; /* Enable or Disable External TMDS encoder */ - UCHAR ucMisc; /* Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB} */ +typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS +{ + UCHAR ucEnable; // Enable or Disable External TMDS encoder + UCHAR ucMisc; // Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB} UCHAR ucPadding[2]; -} ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS; +}ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS; -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION { +typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION +{ ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS sXTmdsEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; /* Caller doesn't need to init this portion */ -} ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION; + WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion +}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION; #define ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2 { +typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2 +{ ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 sXTmdsEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; /* Caller doesn't need to init this portion */ -} ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2; + WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion +}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2; -typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION { +typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION +{ DIG_ENCODER_CONTROL_PARAMETERS sDigEncoder; WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -} EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION; +}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION; /****************************************************************************/ -/* Structures used by DVOEncoderControlTable */ +// Structures used by DVOEncoderControlTable /****************************************************************************/ -/* ucTableFormatRevision=1,ucTableContentRevision=3 */ +//ucTableFormatRevision=1,ucTableContentRevision=3 -/* ucDVOConfig: */ +//ucDVOConfig: #define DVO_ENCODER_CONFIG_RATE_SEL 0x01 #define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 #define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 @@ -1225,21 +1580,22 @@ typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION { #define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 #define DVO_ENCODER_CONFIG_24BIT 0x08 -typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 { +typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 +{ USHORT usPixelClock; UCHAR ucDVOConfig; - UCHAR ucAction; /* ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT */ + UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT UCHAR ucReseved[4]; -} DVO_ENCODER_CONTROL_PARAMETERS_V3; +}DVO_ENCODER_CONTROL_PARAMETERS_V3; #define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 DVO_ENCODER_CONTROL_PARAMETERS_V3 -/* ucTableFormatRevision=1 */ -/* ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for */ -/* bit1=0: non-coherent mode */ -/* =1: coherent mode */ +//ucTableFormatRevision=1 +//ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for +// bit1=0: non-coherent mode +// =1: coherent mode -/* ========================================================================================== */ -/* Only change is here next time when changing encoder parameter definitions again! */ +//========================================================================================== +//Only change is here next time when changing encoder parameter definitions again! #define LVDS_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 #define LVDS_ENCODER_CONTROL_PS_ALLOCATION_LAST LVDS_ENCODER_CONTROL_PARAMETERS_LAST @@ -1252,7 +1608,7 @@ typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 { #define DVO_ENCODER_CONTROL_PARAMETERS_LAST DVO_ENCODER_CONTROL_PARAMETERS #define DVO_ENCODER_CONTROL_PS_ALLOCATION_LAST DVO_ENCODER_CONTROL_PS_ALLOCATION -/* ========================================================================================== */ +//========================================================================================== #define PANEL_ENCODER_MISC_DUAL 0x01 #define PANEL_ENCODER_MISC_COHERENT 0x02 #define PANEL_ENCODER_MISC_TMDS_LINKB 0x04 @@ -1282,14 +1638,14 @@ typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 { #define PANEL_ENCODER_75FRC_F 0x80 /****************************************************************************/ -/* Structures used by SetVoltageTable */ +// Structures used by SetVoltageTable /****************************************************************************/ #define SET_VOLTAGE_TYPE_ASIC_VDDC 1 #define SET_VOLTAGE_TYPE_ASIC_MVDDC 2 #define SET_VOLTAGE_TYPE_ASIC_MVDDQ 3 #define SET_VOLTAGE_TYPE_ASIC_VDDCI 4 #define SET_VOLTAGE_INIT_MODE 5 -#define SET_VOLTAGE_GET_MAX_VOLTAGE 6 /* Gets the Max. voltage for the soldered Asic */ +#define SET_VOLTAGE_GET_MAX_VOLTAGE 6 //Gets the Max. voltage for the soldered Asic #define SET_ASIC_VOLTAGE_MODE_ALL_SOURCE 0x1 #define SET_ASIC_VOLTAGE_MODE_SOURCE_A 0x2 @@ -1299,141 +1655,141 @@ typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 { #define SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL 0x1 #define SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK 0x2 -typedef struct _SET_VOLTAGE_PARAMETERS { - UCHAR ucVoltageType; /* To tell which voltage to set up, VDDC/MVDDC/MVDDQ */ - UCHAR ucVoltageMode; /* To set all, to set source A or source B or ... */ - UCHAR ucVoltageIndex; /* An index to tell which voltage level */ +typedef struct _SET_VOLTAGE_PARAMETERS +{ + UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ + UCHAR ucVoltageMode; // To set all, to set source A or source B or ... + UCHAR ucVoltageIndex; // An index to tell which voltage level UCHAR ucReserved; -} SET_VOLTAGE_PARAMETERS; +}SET_VOLTAGE_PARAMETERS; -typedef struct _SET_VOLTAGE_PARAMETERS_V2 { - UCHAR ucVoltageType; /* To tell which voltage to set up, VDDC/MVDDC/MVDDQ */ - UCHAR ucVoltageMode; /* Not used, maybe use for state machine for differen power mode */ - USHORT usVoltageLevel; /* real voltage level */ -} SET_VOLTAGE_PARAMETERS_V2; +typedef struct _SET_VOLTAGE_PARAMETERS_V2 +{ + UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ + UCHAR ucVoltageMode; // Not used, maybe use for state machine for differen power mode + USHORT usVoltageLevel; // real voltage level +}SET_VOLTAGE_PARAMETERS_V2; -typedef struct _SET_VOLTAGE_PS_ALLOCATION { +typedef struct _SET_VOLTAGE_PS_ALLOCATION +{ SET_VOLTAGE_PARAMETERS sASICSetVoltage; WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -} SET_VOLTAGE_PS_ALLOCATION; +}SET_VOLTAGE_PS_ALLOCATION; /****************************************************************************/ -/* Structures used by TVEncoderControlTable */ +// Structures used by TVEncoderControlTable /****************************************************************************/ -typedef struct _TV_ENCODER_CONTROL_PARAMETERS { - USHORT usPixelClock; /* in 10KHz; for bios convenient */ - UCHAR ucTvStandard; /* See definition "ATOM_TV_NTSC ..." */ - UCHAR ucAction; /* 0: turn off encoder */ - /* 1: setup and turn on encoder */ -} TV_ENCODER_CONTROL_PARAMETERS; +typedef struct _TV_ENCODER_CONTROL_PARAMETERS +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + UCHAR ucTvStandard; // See definition "ATOM_TV_NTSC ..." + UCHAR ucAction; // 0: turn off encoder + // 1: setup and turn on encoder +}TV_ENCODER_CONTROL_PARAMETERS; -typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION { +typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION +{ TV_ENCODER_CONTROL_PARAMETERS sTVEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; /* Don't set this one */ -} TV_ENCODER_CONTROL_PS_ALLOCATION; + WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; // Don't set this one +}TV_ENCODER_CONTROL_PS_ALLOCATION; -/* ==============================Data Table Portion==================================== */ - -#ifdef UEFI_BUILD -#define UTEMP USHORT -#define USHORT void* -#endif +//==============================Data Table Portion==================================== /****************************************************************************/ -/* Structure used in Data.mtb */ +// Structure used in Data.mtb /****************************************************************************/ -typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES { - USHORT UtilityPipeLine; /* Offest for the utility to get parser info,Don't change this position! */ - USHORT MultimediaCapabilityInfo; /* Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios */ - USHORT MultimediaConfigInfo; /* Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios */ - USHORT StandardVESA_Timing; /* Only used by Bios */ - USHORT FirmwareInfo; /* Shared by various SW components,latest version 1.4 */ - USHORT DAC_Info; /* Will be obsolete from R600 */ - USHORT LVDS_Info; /* Shared by various SW components,latest version 1.1 */ - USHORT TMDS_Info; /* Will be obsolete from R600 */ - USHORT AnalogTV_Info; /* Shared by various SW components,latest version 1.1 */ - USHORT SupportedDevicesInfo; /* Will be obsolete from R600 */ - USHORT GPIO_I2C_Info; /* Shared by various SW components,latest version 1.2 will be used from R600 */ - USHORT VRAM_UsageByFirmware; /* Shared by various SW components,latest version 1.3 will be used from R600 */ - USHORT GPIO_Pin_LUT; /* Shared by various SW components,latest version 1.1 */ - USHORT VESA_ToInternalModeLUT; /* Only used by Bios */ - USHORT ComponentVideoInfo; /* Shared by various SW components,latest version 2.1 will be used from R600 */ - USHORT PowerPlayInfo; /* Shared by various SW components,latest version 2.1,new design from R600 */ - USHORT CompassionateData; /* Will be obsolete from R600 */ - USHORT SaveRestoreInfo; /* Only used by Bios */ - USHORT PPLL_SS_Info; /* Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info */ - USHORT OemInfo; /* Defined and used by external SW, should be obsolete soon */ - USHORT XTMDS_Info; /* Will be obsolete from R600 */ - USHORT MclkSS_Info; /* Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used */ - USHORT Object_Header; /* Shared by various SW components,latest version 1.1 */ - USHORT IndirectIOAccess; /* Only used by Bios,this table position can't change at all!! */ - USHORT MC_InitParameter; /* Only used by command table */ - USHORT ASIC_VDDC_Info; /* Will be obsolete from R600 */ - USHORT ASIC_InternalSS_Info; /* New tabel name from R600, used to be called "ASIC_MVDDC_Info" */ - USHORT TV_VideoMode; /* Only used by command table */ - USHORT VRAM_Info; /* Only used by command table, latest version 1.3 */ - USHORT MemoryTrainingInfo; /* Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 */ - USHORT IntegratedSystemInfo; /* Shared by various SW components */ - USHORT ASIC_ProfilingInfo; /* New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 */ - USHORT VoltageObjectInfo; /* Shared by various SW components, latest version 1.1 */ - USHORT PowerSourceInfo; /* Shared by various SW components, latest versoin 1.1 */ -} ATOM_MASTER_LIST_OF_DATA_TABLES; +typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES +{ + USHORT UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position! + USHORT MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios + USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios + USHORT StandardVESA_Timing; // Only used by Bios + USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 + USHORT DAC_Info; // Will be obsolete from R600 + USHORT LVDS_Info; // Shared by various SW components,latest version 1.1 + USHORT TMDS_Info; // Will be obsolete from R600 + USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 + USHORT SupportedDevicesInfo; // Will be obsolete from R600 + USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600 + USHORT VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600 + USHORT GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1 + USHORT VESA_ToInternalModeLUT; // Only used by Bios + USHORT ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600 + USHORT PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600 + USHORT CompassionateData; // Will be obsolete from R600 + USHORT SaveRestoreInfo; // Only used by Bios + USHORT PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info + USHORT OemInfo; // Defined and used by external SW, should be obsolete soon + USHORT XTMDS_Info; // Will be obsolete from R600 + USHORT MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used + USHORT Object_Header; // Shared by various SW components,latest version 1.1 + USHORT IndirectIOAccess; // Only used by Bios,this table position can't change at all!! + USHORT MC_InitParameter; // Only used by command table + USHORT ASIC_VDDC_Info; // Will be obsolete from R600 + USHORT ASIC_InternalSS_Info; // New tabel name from R600, used to be called "ASIC_MVDDC_Info" + USHORT TV_VideoMode; // Only used by command table + USHORT VRAM_Info; // Only used by command table, latest version 1.3 + USHORT MemoryTrainingInfo; // Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 + USHORT IntegratedSystemInfo; // Shared by various SW components + USHORT ASIC_ProfilingInfo; // New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 + USHORT VoltageObjectInfo; // Shared by various SW components, latest version 1.1 + USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 +}ATOM_MASTER_LIST_OF_DATA_TABLES; -#ifdef UEFI_BUILD -#define USHORT UTEMP -#endif - -typedef struct _ATOM_MASTER_DATA_TABLE { +typedef struct _ATOM_MASTER_DATA_TABLE +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; -} ATOM_MASTER_DATA_TABLE; +}ATOM_MASTER_DATA_TABLE; /****************************************************************************/ -/* Structure used in MultimediaCapabilityInfoTable */ +// Structure used in MultimediaCapabilityInfoTable /****************************************************************************/ -typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO { +typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulSignature; /* HW info table signature string "$ATI" */ - UCHAR ucI2C_Type; /* I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc) */ - UCHAR ucTV_OutInfo; /* Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7) */ - UCHAR ucVideoPortInfo; /* Provides the video port capabilities */ - UCHAR ucHostPortInfo; /* Provides host port configuration information */ -} ATOM_MULTIMEDIA_CAPABILITY_INFO; + ULONG ulSignature; // HW info table signature string "$ATI" + UCHAR ucI2C_Type; // I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc) + UCHAR ucTV_OutInfo; // Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7) + UCHAR ucVideoPortInfo; // Provides the video port capabilities + UCHAR ucHostPortInfo; // Provides host port configuration information +}ATOM_MULTIMEDIA_CAPABILITY_INFO; /****************************************************************************/ -/* Structure used in MultimediaConfigInfoTable */ +// Structure used in MultimediaConfigInfoTable /****************************************************************************/ -typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO { +typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulSignature; /* MM info table signature sting "$MMT" */ - UCHAR ucTunerInfo; /* Type of tuner installed on the adapter (4:0) and video input for tuner (7:5) */ - UCHAR ucAudioChipInfo; /* List the audio chip type (3:0) product type (4) and OEM revision (7:5) */ - UCHAR ucProductID; /* Defines as OEM ID or ATI board ID dependent on product type setting */ - UCHAR ucMiscInfo1; /* Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7) */ - UCHAR ucMiscInfo2; /* I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6) */ - UCHAR ucMiscInfo3; /* Video Decoder Type (3:0) Video In Standard/Crystal (7:4) */ - UCHAR ucMiscInfo4; /* Video Decoder Host Config (2:0) reserved (7:3) */ - UCHAR ucVideoInput0Info; /* Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */ - UCHAR ucVideoInput1Info; /* Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */ - UCHAR ucVideoInput2Info; /* Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */ - UCHAR ucVideoInput3Info; /* Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */ - UCHAR ucVideoInput4Info; /* Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) */ -} ATOM_MULTIMEDIA_CONFIG_INFO; + ULONG ulSignature; // MM info table signature sting "$MMT" + UCHAR ucTunerInfo; // Type of tuner installed on the adapter (4:0) and video input for tuner (7:5) + UCHAR ucAudioChipInfo; // List the audio chip type (3:0) product type (4) and OEM revision (7:5) + UCHAR ucProductID; // Defines as OEM ID or ATI board ID dependent on product type setting + UCHAR ucMiscInfo1; // Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7) + UCHAR ucMiscInfo2; // I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6) + UCHAR ucMiscInfo3; // Video Decoder Type (3:0) Video In Standard/Crystal (7:4) + UCHAR ucMiscInfo4; // Video Decoder Host Config (2:0) reserved (7:3) + UCHAR ucVideoInput0Info;// Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) + UCHAR ucVideoInput1Info;// Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) + UCHAR ucVideoInput2Info;// Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) + UCHAR ucVideoInput3Info;// Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) + UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) +}ATOM_MULTIMEDIA_CONFIG_INFO; -/****************************************************************************/ -/* Structures used in FirmwareInfoTable */ -/****************************************************************************/ +/****************************************************************************/ +// Structures used in FirmwareInfoTable +/****************************************************************************/ -/* usBIOSCapability Definition: */ -/* Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */ -/* Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */ -/* Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */ -/* Others: Reserved */ +// usBIOSCapability Defintion: +// Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; +// Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; +// Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; +// Others: Reserved #define ATOM_BIOS_INFO_ATOM_FIRMWARE_POSTED 0x0001 #define ATOM_BIOS_INFO_DUAL_CRTC_SUPPORT 0x0002 #define ATOM_BIOS_INFO_EXTENDED_DESKTOP_SUPPORT 0x0004 -#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT 0x0008 -#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT 0x0010 +#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT 0x0008 // (valid from v1.1 ~v1.4):=1: memclk SS enable, =0 memclk SS disable. +#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT 0x0010 // (valid from v1.1 ~v1.4):=1: engclk SS enable, =0 engclk SS disable. #define ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU 0x0020 #define ATOM_BIOS_INFO_WMI_SUPPORT 0x0040 #define ATOM_BIOS_INFO_PPMODE_ASSIGNGED_BY_SYSTEM 0x0080 @@ -1441,11 +1797,14 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO { #define ATOM_BIOS_INFO_HYPERMEMORY_SIZE_MASK 0x1E00 #define ATOM_BIOS_INFO_VPOST_WITHOUT_FIRST_MODE_SET 0x2000 #define ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE 0x4000 +#define ATOM_BIOS_INFO_MEMORY_CLOCK_EXT_SS_SUPPORT 0x0008 // (valid from v2.1 ): =1: memclk ss enable with external ss chip +#define ATOM_BIOS_INFO_ENGINE_CLOCK_EXT_SS_SUPPORT 0x0010 // (valid from v2.1 ): =1: engclk ss enable with external ss chip #ifndef _H2INC -/* Please don't add or expand this bitfield structure below, this one will retire soon.! */ -typedef struct _ATOM_FIRMWARE_CAPABILITY { +//Please don't add or expand this bitfield structure below, this one will retire soon.! +typedef struct _ATOM_FIRMWARE_CAPABILITY +{ #if ATOM_BIG_ENDIAN USHORT Reserved:3; USHORT HyperMemory_Size:4; @@ -1471,202 +1830,249 @@ typedef struct _ATOM_FIRMWARE_CAPABILITY { USHORT HyperMemory_Size:4; USHORT Reserved:3; #endif -} ATOM_FIRMWARE_CAPABILITY; +}ATOM_FIRMWARE_CAPABILITY; -typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS { +typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS +{ ATOM_FIRMWARE_CAPABILITY sbfAccess; USHORT susAccess; -} ATOM_FIRMWARE_CAPABILITY_ACCESS; +}ATOM_FIRMWARE_CAPABILITY_ACCESS; #else -typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS { +typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS +{ USHORT susAccess; -} ATOM_FIRMWARE_CAPABILITY_ACCESS; +}ATOM_FIRMWARE_CAPABILITY_ACCESS; #endif -typedef struct _ATOM_FIRMWARE_INFO { +typedef struct _ATOM_FIRMWARE_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; /* In 10Khz unit */ - ULONG ulDefaultMemoryClock; /* In 10Khz unit */ - ULONG ulDriverTargetEngineClock; /* In 10Khz unit */ - ULONG ulDriverTargetMemoryClock; /* In 10Khz unit */ - ULONG ulMaxEngineClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxMemoryClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxPixelClockPLL_Output; /* In 10Khz unit */ - ULONG ulASICMaxEngineClock; /* In 10Khz unit */ - ULONG ulASICMaxMemoryClock; /* In 10Khz unit */ + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulDriverTargetEngineClock; //In 10Khz unit + ULONG ulDriverTargetMemoryClock; //In 10Khz unit + ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit + ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulASICMaxEngineClock; //In 10Khz unit + ULONG ulASICMaxMemoryClock; //In 10Khz unit UCHAR ucASICMaxTemperature; - UCHAR ucPadding[3]; /* Don't use them */ - ULONG aulReservedForBIOS[3]; /* Don't use them */ - USHORT usMinEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Output; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Output; /* In 10Khz unit */ - USHORT usMaxPixelClock; /* In 10Khz unit, Max. Pclk */ - USHORT usMinPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMinPixelClockPLL_Output; /* In 10Khz unit, the definitions above can't change!!! */ + UCHAR ucPadding[3]; //Don't use them + ULONG aulReservedForBIOS[3]; //Don't use them + USHORT usMinEngineClockPLL_Input; //In 10Khz unit + USHORT usMaxEngineClockPLL_Input; //In 10Khz unit + USHORT usMinEngineClockPLL_Output; //In 10Khz unit + USHORT usMinMemoryClockPLL_Input; //In 10Khz unit + USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit + USHORT usMinMemoryClockPLL_Output; //In 10Khz unit + USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usMinPixelClockPLL_Output; //In 10Khz unit, the definitions above can't change!!! ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; /* In 10Khz unit */ - USHORT usPM_RTS_Location; /* RTS PM4 starting location in ROM in 1Kb unit */ - UCHAR ucPM_RTS_StreamSize; /* RTS PM4 packets in Kb unit */ - UCHAR ucDesign_ID; /* Indicate what is the board design */ - UCHAR ucMemoryModule_ID; /* Indicate what is the board design */ -} ATOM_FIRMWARE_INFO; + USHORT usReferenceClock; //In 10Khz unit + USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit + UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit + UCHAR ucDesign_ID; //Indicate what is the board design + UCHAR ucMemoryModule_ID; //Indicate what is the board design +}ATOM_FIRMWARE_INFO; -typedef struct _ATOM_FIRMWARE_INFO_V1_2 { +typedef struct _ATOM_FIRMWARE_INFO_V1_2 +{ ATOM_COMMON_TABLE_HEADER sHeader; ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; /* In 10Khz unit */ - ULONG ulDefaultMemoryClock; /* In 10Khz unit */ - ULONG ulDriverTargetEngineClock; /* In 10Khz unit */ - ULONG ulDriverTargetMemoryClock; /* In 10Khz unit */ - ULONG ulMaxEngineClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxMemoryClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxPixelClockPLL_Output; /* In 10Khz unit */ - ULONG ulASICMaxEngineClock; /* In 10Khz unit */ - ULONG ulASICMaxMemoryClock; /* In 10Khz unit */ + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulDriverTargetEngineClock; //In 10Khz unit + ULONG ulDriverTargetMemoryClock; //In 10Khz unit + ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit + ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulASICMaxEngineClock; //In 10Khz unit + ULONG ulASICMaxMemoryClock; //In 10Khz unit UCHAR ucASICMaxTemperature; UCHAR ucMinAllowedBL_Level; - UCHAR ucPadding[2]; /* Don't use them */ - ULONG aulReservedForBIOS[2]; /* Don't use them */ - ULONG ulMinPixelClockPLL_Output; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Output; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Output; /* In 10Khz unit */ - USHORT usMaxPixelClock; /* In 10Khz unit, Max. Pclk */ - USHORT usMinPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMinPixelClockPLL_Output; /* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */ + UCHAR ucPadding[2]; //Don't use them + ULONG aulReservedForBIOS[2]; //Don't use them + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit + USHORT usMinEngineClockPLL_Input; //In 10Khz unit + USHORT usMaxEngineClockPLL_Input; //In 10Khz unit + USHORT usMinEngineClockPLL_Output; //In 10Khz unit + USHORT usMinMemoryClockPLL_Input; //In 10Khz unit + USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit + USHORT usMinMemoryClockPLL_Output; //In 10Khz unit + USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; /* In 10Khz unit */ - USHORT usPM_RTS_Location; /* RTS PM4 starting location in ROM in 1Kb unit */ - UCHAR ucPM_RTS_StreamSize; /* RTS PM4 packets in Kb unit */ - UCHAR ucDesign_ID; /* Indicate what is the board design */ - UCHAR ucMemoryModule_ID; /* Indicate what is the board design */ -} ATOM_FIRMWARE_INFO_V1_2; + USHORT usReferenceClock; //In 10Khz unit + USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit + UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit + UCHAR ucDesign_ID; //Indicate what is the board design + UCHAR ucMemoryModule_ID; //Indicate what is the board design +}ATOM_FIRMWARE_INFO_V1_2; -typedef struct _ATOM_FIRMWARE_INFO_V1_3 { +typedef struct _ATOM_FIRMWARE_INFO_V1_3 +{ ATOM_COMMON_TABLE_HEADER sHeader; ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; /* In 10Khz unit */ - ULONG ulDefaultMemoryClock; /* In 10Khz unit */ - ULONG ulDriverTargetEngineClock; /* In 10Khz unit */ - ULONG ulDriverTargetMemoryClock; /* In 10Khz unit */ - ULONG ulMaxEngineClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxMemoryClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxPixelClockPLL_Output; /* In 10Khz unit */ - ULONG ulASICMaxEngineClock; /* In 10Khz unit */ - ULONG ulASICMaxMemoryClock; /* In 10Khz unit */ + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulDriverTargetEngineClock; //In 10Khz unit + ULONG ulDriverTargetMemoryClock; //In 10Khz unit + ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit + ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulASICMaxEngineClock; //In 10Khz unit + ULONG ulASICMaxMemoryClock; //In 10Khz unit UCHAR ucASICMaxTemperature; UCHAR ucMinAllowedBL_Level; - UCHAR ucPadding[2]; /* Don't use them */ - ULONG aulReservedForBIOS; /* Don't use them */ - ULONG ul3DAccelerationEngineClock; /* In 10Khz unit */ - ULONG ulMinPixelClockPLL_Output; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Output; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Output; /* In 10Khz unit */ - USHORT usMaxPixelClock; /* In 10Khz unit, Max. Pclk */ - USHORT usMinPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMinPixelClockPLL_Output; /* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */ + UCHAR ucPadding[2]; //Don't use them + ULONG aulReservedForBIOS; //Don't use them + ULONG ul3DAccelerationEngineClock;//In 10Khz unit + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit + USHORT usMinEngineClockPLL_Input; //In 10Khz unit + USHORT usMaxEngineClockPLL_Input; //In 10Khz unit + USHORT usMinEngineClockPLL_Output; //In 10Khz unit + USHORT usMinMemoryClockPLL_Input; //In 10Khz unit + USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit + USHORT usMinMemoryClockPLL_Output; //In 10Khz unit + USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; /* In 10Khz unit */ - USHORT usPM_RTS_Location; /* RTS PM4 starting location in ROM in 1Kb unit */ - UCHAR ucPM_RTS_StreamSize; /* RTS PM4 packets in Kb unit */ - UCHAR ucDesign_ID; /* Indicate what is the board design */ - UCHAR ucMemoryModule_ID; /* Indicate what is the board design */ -} ATOM_FIRMWARE_INFO_V1_3; + USHORT usReferenceClock; //In 10Khz unit + USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit + UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit + UCHAR ucDesign_ID; //Indicate what is the board design + UCHAR ucMemoryModule_ID; //Indicate what is the board design +}ATOM_FIRMWARE_INFO_V1_3; -typedef struct _ATOM_FIRMWARE_INFO_V1_4 { +typedef struct _ATOM_FIRMWARE_INFO_V1_4 +{ ATOM_COMMON_TABLE_HEADER sHeader; ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; /* In 10Khz unit */ - ULONG ulDefaultMemoryClock; /* In 10Khz unit */ - ULONG ulDriverTargetEngineClock; /* In 10Khz unit */ - ULONG ulDriverTargetMemoryClock; /* In 10Khz unit */ - ULONG ulMaxEngineClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxMemoryClockPLL_Output; /* In 10Khz unit */ - ULONG ulMaxPixelClockPLL_Output; /* In 10Khz unit */ - ULONG ulASICMaxEngineClock; /* In 10Khz unit */ - ULONG ulASICMaxMemoryClock; /* In 10Khz unit */ + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulDriverTargetEngineClock; //In 10Khz unit + ULONG ulDriverTargetMemoryClock; //In 10Khz unit + ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit + ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulASICMaxEngineClock; //In 10Khz unit + ULONG ulASICMaxMemoryClock; //In 10Khz unit UCHAR ucASICMaxTemperature; UCHAR ucMinAllowedBL_Level; - USHORT usBootUpVDDCVoltage; /* In MV unit */ - USHORT usLcdMinPixelClockPLL_Output; /* In MHz unit */ - USHORT usLcdMaxPixelClockPLL_Output; /* In MHz unit */ - ULONG ul3DAccelerationEngineClock; /* In 10Khz unit */ - ULONG ulMinPixelClockPLL_Output; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxEngineClockPLL_Input; /* In 10Khz unit */ - USHORT usMinEngineClockPLL_Output; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxMemoryClockPLL_Input; /* In 10Khz unit */ - USHORT usMinMemoryClockPLL_Output; /* In 10Khz unit */ - USHORT usMaxPixelClock; /* In 10Khz unit, Max. Pclk */ - USHORT usMinPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMaxPixelClockPLL_Input; /* In 10Khz unit */ - USHORT usMinPixelClockPLL_Output; /* In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output */ - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; /* In 10Khz unit */ - USHORT usPM_RTS_Location; /* RTS PM4 starting location in ROM in 1Kb unit */ - UCHAR ucPM_RTS_StreamSize; /* RTS PM4 packets in Kb unit */ - UCHAR ucDesign_ID; /* Indicate what is the board design */ - UCHAR ucMemoryModule_ID; /* Indicate what is the board design */ -} ATOM_FIRMWARE_INFO_V1_4; + USHORT usBootUpVDDCVoltage; //In MV unit + USHORT usLcdMinPixelClockPLL_Output; // In MHz unit + USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit + ULONG ul3DAccelerationEngineClock;//In 10Khz unit + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit + USHORT usMinEngineClockPLL_Input; //In 10Khz unit + USHORT usMaxEngineClockPLL_Input; //In 10Khz unit + USHORT usMinEngineClockPLL_Output; //In 10Khz unit + USHORT usMinMemoryClockPLL_Input; //In 10Khz unit + USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit + USHORT usMinMemoryClockPLL_Output; //In 10Khz unit + USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output + ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; + USHORT usReferenceClock; //In 10Khz unit + USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit + UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit + UCHAR ucDesign_ID; //Indicate what is the board design + UCHAR ucMemoryModule_ID; //Indicate what is the board design +}ATOM_FIRMWARE_INFO_V1_4; -#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V1_4 +//the structure below to be used from Cypress +typedef struct _ATOM_FIRMWARE_INFO_V2_1 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ULONG ulFirmwareRevision; + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulReserved1; + ULONG ulReserved2; + ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit + ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulBinaryAlteredInfo; //Was ulASICMaxEngineClock + ULONG ulDefaultDispEngineClkFreq; //In 10Khz unit + UCHAR ucReserved1; //Was ucASICMaxTemperature; + UCHAR ucMinAllowedBL_Level; + USHORT usBootUpVDDCVoltage; //In MV unit + USHORT usLcdMinPixelClockPLL_Output; // In MHz unit + USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit + ULONG ulReserved4; //Was ulAsicMaximumVoltage + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit + USHORT usMinEngineClockPLL_Input; //In 10Khz unit + USHORT usMaxEngineClockPLL_Input; //In 10Khz unit + USHORT usMinEngineClockPLL_Output; //In 10Khz unit + USHORT usMinMemoryClockPLL_Input; //In 10Khz unit + USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit + USHORT usMinMemoryClockPLL_Output; //In 10Khz unit + USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output + ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; + USHORT usCoreReferenceClock; //In 10Khz unit + USHORT usMemoryReferenceClock; //In 10Khz unit + USHORT usUniphyDPModeExtClkFreq; //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock + UCHAR ucMemoryModule_ID; //Indicate what is the board design + UCHAR ucReserved4[3]; +}ATOM_FIRMWARE_INFO_V2_1; + + +#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_1 /****************************************************************************/ -/* Structures used in IntegratedSystemInfoTable */ +// Structures used in IntegratedSystemInfoTable /****************************************************************************/ #define IGP_CAP_FLAG_DYNAMIC_CLOCK_EN 0x2 #define IGP_CAP_FLAG_AC_CARD 0x4 #define IGP_CAP_FLAG_SDVO_CARD 0x8 #define IGP_CAP_FLAG_POSTDIV_BY_2_MODE 0x10 -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO { +typedef struct _ATOM_INTEGRATED_SYSTEM_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; /* in 10kHz unit */ - ULONG ulBootUpMemoryClock; /* in 10kHz unit */ - ULONG ulMaxSystemMemoryClock; /* in 10kHz unit */ - ULONG ulMinSystemMemoryClock; /* in 10kHz unit */ + ULONG ulBootUpEngineClock; //in 10kHz unit + ULONG ulBootUpMemoryClock; //in 10kHz unit + ULONG ulMaxSystemMemoryClock; //in 10kHz unit + ULONG ulMinSystemMemoryClock; //in 10kHz unit UCHAR ucNumberOfCyclesInPeriodHi; - UCHAR ucLCDTimingSel; /* =0:not valid.!=0 sel this timing descriptor from LCD EDID. */ + UCHAR ucLCDTimingSel; //=0:not valid.!=0 sel this timing descriptor from LCD EDID. USHORT usReserved1; - USHORT usInterNBVoltageLow; /* An intermidiate PMW value to set the voltage */ - USHORT usInterNBVoltageHigh; /* Another intermidiate PMW value to set the voltage */ + USHORT usInterNBVoltageLow; //An intermidiate PMW value to set the voltage + USHORT usInterNBVoltageHigh; //Another intermidiate PMW value to set the voltage ULONG ulReserved[2]; - USHORT usFSBClock; /* In MHz unit */ - USHORT usCapabilityFlag; /* Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable */ - /* Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card */ - /* Bit[4]==1: P/2 mode, ==0: P/1 mode */ - USHORT usPCIENBCfgReg7; /* bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal */ - USHORT usK8MemoryClock; /* in MHz unit */ - USHORT usK8SyncStartDelay; /* in 0.01 us unit */ - USHORT usK8DataReturnTime; /* in 0.01 us unit */ + USHORT usFSBClock; //In MHz unit + USHORT usCapabilityFlag; //Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable + //Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card + //Bit[4]==1: P/2 mode, ==0: P/1 mode + USHORT usPCIENBCfgReg7; //bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal + USHORT usK8MemoryClock; //in MHz unit + USHORT usK8SyncStartDelay; //in 0.01 us unit + USHORT usK8DataReturnTime; //in 0.01 us unit UCHAR ucMaxNBVoltage; UCHAR ucMinNBVoltage; - UCHAR ucMemoryType; /* [7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved */ - UCHAR ucNumberOfCyclesInPeriod; /* CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod */ - UCHAR ucStartingPWM_HighTime; /* CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime */ - UCHAR ucHTLinkWidth; /* 16 bit vs. 8 bit */ + UCHAR ucMemoryType; //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved + UCHAR ucNumberOfCyclesInPeriod; //CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod + UCHAR ucStartingPWM_HighTime; //CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime + UCHAR ucHTLinkWidth; //16 bit vs. 8 bit UCHAR ucMaxNBVoltageHigh; UCHAR ucMinNBVoltageHigh; -} ATOM_INTEGRATED_SYSTEM_INFO; +}ATOM_INTEGRATED_SYSTEM_INFO; /* Explanation on entries in ATOM_INTEGRATED_SYSTEM_INFO ulBootUpMemoryClock: For Intel IGP,it's the UMA system memory clock @@ -1693,10 +2099,12 @@ ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high ucMaxNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all. ucMinNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all. + usInterNBVoltageLow: Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all. usInterNBVoltageHigh: Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all. */ + /* The following IGP table is introduced from RS780, which is supposed to be put by SBIOS in FB before IGP VBIOS starts VPOST; Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need. @@ -1705,20 +2113,22 @@ The enough reservation should allow us to never change table revisions. Whenever SW components can access the IGP system infor structure in the same way as before */ -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 { + +typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 +{ ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; /* in 10kHz unit */ - ULONG ulReserved1[2]; /* must be 0x0 for the reserved */ - ULONG ulBootUpUMAClock; /* in 10kHz unit */ - ULONG ulBootUpSidePortClock; /* in 10kHz unit */ - ULONG ulMinSidePortClock; /* in 10kHz unit */ - ULONG ulReserved2[6]; /* must be 0x0 for the reserved */ - ULONG ulSystemConfig; /* see explanation below */ + ULONG ulBootUpEngineClock; //in 10kHz unit + ULONG ulReserved1[2]; //must be 0x0 for the reserved + ULONG ulBootUpUMAClock; //in 10kHz unit + ULONG ulBootUpSidePortClock; //in 10kHz unit + ULONG ulMinSidePortClock; //in 10kHz unit + ULONG ulReserved2[6]; //must be 0x0 for the reserved + ULONG ulSystemConfig; //see explanation below ULONG ulBootUpReqDisplayVector; ULONG ulOtherDisplayMisc; ULONG ulDDISlot1Config; ULONG ulDDISlot2Config; - UCHAR ucMemoryType; /* [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved */ + UCHAR ucMemoryType; //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved UCHAR ucUMAChannelNumber; UCHAR ucDockingPinBit; UCHAR ucDockingPinPolarity; @@ -1728,21 +2138,23 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 { USHORT usMaxNBVoltage; USHORT usMinNBVoltage; USHORT usBootUpNBVoltage; - ULONG ulHTLinkFreq; /* in 10Khz */ + ULONG ulHTLinkFreq; //in 10Khz USHORT usMinHTLinkWidth; USHORT usMaxHTLinkWidth; USHORT usUMASyncStartDelay; USHORT usUMADataReturnTime; USHORT usLinkStatusZeroTime; - USHORT usReserved; - ULONG ulHighVoltageHTLinkFreq; /* in 10Khz */ - ULONG ulLowVoltageHTLinkFreq; /* in 10Khz */ + USHORT usDACEfuse; //for storing badgap value (for RS880 only) + ULONG ulHighVoltageHTLinkFreq; // in 10Khz + ULONG ulLowVoltageHTLinkFreq; // in 10Khz USHORT usMaxUpStreamHTLinkWidth; USHORT usMaxDownStreamHTLinkWidth; USHORT usMinUpStreamHTLinkWidth; USHORT usMinDownStreamHTLinkWidth; - ULONG ulReserved3[97]; /* must be 0x0 */ -} ATOM_INTEGRATED_SYSTEM_INFO_V2; + USHORT usFirmwareVersion; //0 means FW is not supported. Otherwise it's the FW version loaded by SBIOS and driver should enable FW. + USHORT usFullT0Time; // Input to calculate minimum HT link change time required by NB P-State. Unit is 0.01us. + ULONG ulReserved3[96]; //must be 0x0 +}ATOM_INTEGRATED_SYSTEM_INFO_V2; /* ulBootUpEngineClock: Boot-up Engine Clock in 10Khz; @@ -1764,21 +2176,30 @@ Bit[6]=1: High Voltage requested for all power states. In this case, voltage wil =0: Voltage settings is determined by powerplay table. Bit[7]=1: Enable CLMC as hybrid Mode. CDLD and CILR will be disabled in this case and we're using legacy C1E. This is workaround for CPU(Griffin) performance issue. =0: Enable CLMC as regular mode, CDLD and CILR will be enabled. +Bit[8]=1: CDLF is supported and enabled on current system. + =0: CDLF is not supported or enabled on current system. +Bit[9]=1: DLL Shut Down feature is enabled on current system. + =0: DLL Shut Down feature is not enabled or supported on current system. ulBootUpReqDisplayVector: This dword is a bit vector indicates what display devices are requested during boot-up. Refer to ATOM_DEVICE_xxx_SUPPORT for the bit vector definitions. ulOtherDisplayMisc: [15:8]- Bootup LCD Expansion selection; 0-center, 1-full panel size expansion; - [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSuppportedStd definition; + [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSupportedStd definition; ulDDISlot1Config: Describes the PCIE lane configuration on this DDI PCIE slot (ADD2 card) or connector (Mobile design). [3:0] - Bit vector to indicate PCIE lane config of the DDI slot/connector on chassis (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12) - [7:4] - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12) + [7:4] - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 4=1 lane 3:0; bit 5=1 lane 7:4; bit 6=1 lane 11:8; bit 7=1 lane 15:12) + When a DDI connector is not "paired" (meaming two connections mutualexclusive on chassis or docking, only one of them can be connected at one time. + in both chassis and docking, SBIOS has to duplicate the same PCIE lane info from chassis to docking or vice versa. For example: + one DDI connector is only populated in docking with PCIE lane 8-11, but there is no paired connection on chassis, SBIOS has to copy bit 6 to bit 2. + [15:8] - Lane configuration attribute; [23:16]- Connector type, possible value: CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D CONNECTOR_OBJECT_ID_HDMI_TYPE_A CONNECTOR_OBJECT_ID_DISPLAYPORT + CONNECTOR_OBJECT_ID_eDP [31:24]- Reserved ulDDISlot2Config: Same as Slot1. @@ -1794,11 +2215,13 @@ ucDockingPinPolarity:Polarity of the pin when docked; ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, other bits reserved for now and must be 0x0 usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. + usMaxNBVoltage:Max. voltage control value in either PWM or GPIO mode. usMinNBVoltage:Min. voltage control value in either PWM or GPIO mode. GPIO mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=0 PWM mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=1 GPU SW don't control mode: usMaxNBVoltage & usMinNBVoltage=0 and no care about ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE + usBootUpNBVoltage:Boot-up voltage regulator dependent PWM value. ulHTLinkFreq: Bootup HT link Frequency in 10Khz. @@ -1827,6 +2250,7 @@ usMinUpStreamHTLinkWidth: Asymmetric link width support in the future, to rep usMinDownStreamHTLinkWidth: same as above. */ + #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 #define SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE 0x00000004 @@ -1835,6 +2259,8 @@ usMinDownStreamHTLinkWidth: same as above. #define SYSTEM_CONFIG_CDLW_ENABLED 0x00000020 #define SYSTEM_CONFIG_HIGH_VOLTAGE_REQUESTED 0x00000040 #define SYSTEM_CONFIG_CLMC_HYBRID_MODE_ENABLED 0x00000080 +#define SYSTEM_CONFIG_CDLF_ENABLED 0x00000100 +#define SYSTEM_CONFIG_DLL_SHUTDOWN_ENABLED 0x00000200 #define IGP_DDI_SLOT_LANE_CONFIG_MASK 0x000000FF @@ -1851,6 +2277,41 @@ usMinDownStreamHTLinkWidth: same as above. #define IGP_DDI_SLOT_CONNECTOR_TYPE_MASK 0x00FF0000 +// IntegratedSystemInfoTable new Rev is V5 after V2, because of the real rev of V2 is v1.4. This rev is used for RR +typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ULONG ulBootUpEngineClock; //in 10kHz unit + ULONG ulDentistVCOFreq; //Dentist VCO clock in 10kHz unit, the source of GPU SCLK, LCLK, UCLK and VCLK. + ULONG ulLClockFreq; //GPU Lclk freq in 10kHz unit, have relationship with NCLK in NorthBridge + ULONG ulBootUpUMAClock; //in 10kHz unit + ULONG ulReserved1[8]; //must be 0x0 for the reserved + ULONG ulBootUpReqDisplayVector; + ULONG ulOtherDisplayMisc; + ULONG ulReserved2[4]; //must be 0x0 for the reserved + ULONG ulSystemConfig; //TBD + ULONG ulCPUCapInfo; //TBD + USHORT usMaxNBVoltage; //high NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; + USHORT usMinNBVoltage; //low NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; + USHORT usBootUpNBVoltage; //boot up NB voltage + UCHAR ucHtcTmpLmt; //bit [22:16] of D24F3x64 Hardware Thermal Control (HTC) Register, may not be needed, TBD + UCHAR ucTjOffset; //bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed, TBD + ULONG ulReserved3[4]; //must be 0x0 for the reserved + ULONG ulDDISlot1Config; //see above ulDDISlot1Config definition + ULONG ulDDISlot2Config; + ULONG ulDDISlot3Config; + ULONG ulDDISlot4Config; + ULONG ulReserved4[4]; //must be 0x0 for the reserved + UCHAR ucMemoryType; //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved + UCHAR ucUMAChannelNumber; + USHORT usReserved; + ULONG ulReserved5[4]; //must be 0x0 for the reserved + ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10];//arrays with values for CSR M3 arbiter for default + ULONG ulCSR_M3_ARB_CNTL_UVD[10]; //arrays with values for CSR M3 arbiter for UVD playback + ULONG ulCSR_M3_ARB_CNTL_FS3D[10];//arrays with values for CSR M3 arbiter for Full Screen 3D applications + ULONG ulReserved6[61]; //must be 0x0 +}ATOM_INTEGRATED_SYSTEM_INFO_V5; + #define ATOM_CRT_INT_ENCODER1_INDEX 0x00000000 #define ATOM_LCD_INT_ENCODER1_INDEX 0x00000001 #define ATOM_TV_INT_ENCODER1_INDEX 0x00000002 @@ -1866,7 +2327,7 @@ usMinDownStreamHTLinkWidth: same as above. #define ATOM_DFP_INT_ENCODER3_INDEX 0x0000000C #define ATOM_DFP_INT_ENCODER4_INDEX 0x0000000D -/* define ASIC internal encoder id ( bit vector ) */ +// define ASIC internal encoder id ( bit vector ), used for CRTC_SourceSelTable #define ASIC_INT_DAC1_ENCODER_ID 0x00 #define ASIC_INT_TV_ENCODER_ID 0x02 #define ASIC_INT_DIG1_ENCODER_ID 0x03 @@ -1875,10 +2336,24 @@ usMinDownStreamHTLinkWidth: same as above. #define ASIC_INT_DVO_ENCODER_ID 0x07 #define ASIC_INT_DIG2_ENCODER_ID 0x09 #define ASIC_EXT_DIG_ENCODER_ID 0x05 +#define ASIC_EXT_DIG2_ENCODER_ID 0x08 +#define ASIC_INT_DIG3_ENCODER_ID 0x0a +#define ASIC_INT_DIG4_ENCODER_ID 0x0b +#define ASIC_INT_DIG5_ENCODER_ID 0x0c +#define ASIC_INT_DIG6_ENCODER_ID 0x0d -/* define Encoder attribute */ +//define Encoder attribute #define ATOM_ANALOG_ENCODER 0 #define ATOM_DIGITAL_ENCODER 1 +#define ATOM_DP_ENCODER 2 + +#define ATOM_ENCODER_ENUM_MASK 0x70 +#define ATOM_ENCODER_ENUM_ID1 0x00 +#define ATOM_ENCODER_ENUM_ID2 0x10 +#define ATOM_ENCODER_ENUM_ID3 0x20 +#define ATOM_ENCODER_ENUM_ID4 0x30 +#define ATOM_ENCODER_ENUM_ID5 0x40 +#define ATOM_ENCODER_ENUM_ID6 0x50 #define ATOM_DEVICE_CRT1_INDEX 0x00000000 #define ATOM_DEVICE_LCD1_INDEX 0x00000001 @@ -1886,45 +2361,40 @@ usMinDownStreamHTLinkWidth: same as above. #define ATOM_DEVICE_DFP1_INDEX 0x00000003 #define ATOM_DEVICE_CRT2_INDEX 0x00000004 #define ATOM_DEVICE_LCD2_INDEX 0x00000005 -#define ATOM_DEVICE_TV2_INDEX 0x00000006 +#define ATOM_DEVICE_DFP6_INDEX 0x00000006 #define ATOM_DEVICE_DFP2_INDEX 0x00000007 #define ATOM_DEVICE_CV_INDEX 0x00000008 #define ATOM_DEVICE_DFP3_INDEX 0x00000009 #define ATOM_DEVICE_DFP4_INDEX 0x0000000A #define ATOM_DEVICE_DFP5_INDEX 0x0000000B + #define ATOM_DEVICE_RESERVEDC_INDEX 0x0000000C #define ATOM_DEVICE_RESERVEDD_INDEX 0x0000000D #define ATOM_DEVICE_RESERVEDE_INDEX 0x0000000E #define ATOM_DEVICE_RESERVEDF_INDEX 0x0000000F #define ATOM_MAX_SUPPORTED_DEVICE_INFO (ATOM_DEVICE_DFP3_INDEX+1) #define ATOM_MAX_SUPPORTED_DEVICE_INFO_2 ATOM_MAX_SUPPORTED_DEVICE_INFO -#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3 (ATOM_DEVICE_DFP5_INDEX + 1) +#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3 (ATOM_DEVICE_DFP5_INDEX + 1 ) #define ATOM_MAX_SUPPORTED_DEVICE (ATOM_DEVICE_RESERVEDF_INDEX+1) -#define ATOM_DEVICE_CRT1_SUPPORT (0x1L << ATOM_DEVICE_CRT1_INDEX) -#define ATOM_DEVICE_LCD1_SUPPORT (0x1L << ATOM_DEVICE_LCD1_INDEX) -#define ATOM_DEVICE_TV1_SUPPORT (0x1L << ATOM_DEVICE_TV1_INDEX) -#define ATOM_DEVICE_DFP1_SUPPORT (0x1L << ATOM_DEVICE_DFP1_INDEX) -#define ATOM_DEVICE_CRT2_SUPPORT (0x1L << ATOM_DEVICE_CRT2_INDEX) -#define ATOM_DEVICE_LCD2_SUPPORT (0x1L << ATOM_DEVICE_LCD2_INDEX) -#define ATOM_DEVICE_TV2_SUPPORT (0x1L << ATOM_DEVICE_TV2_INDEX) -#define ATOM_DEVICE_DFP2_SUPPORT (0x1L << ATOM_DEVICE_DFP2_INDEX) -#define ATOM_DEVICE_CV_SUPPORT (0x1L << ATOM_DEVICE_CV_INDEX) -#define ATOM_DEVICE_DFP3_SUPPORT (0x1L << ATOM_DEVICE_DFP3_INDEX) +#define ATOM_DEVICE_CRT1_SUPPORT (0x1L << ATOM_DEVICE_CRT1_INDEX ) +#define ATOM_DEVICE_LCD1_SUPPORT (0x1L << ATOM_DEVICE_LCD1_INDEX ) +#define ATOM_DEVICE_TV1_SUPPORT (0x1L << ATOM_DEVICE_TV1_INDEX ) +#define ATOM_DEVICE_DFP1_SUPPORT (0x1L << ATOM_DEVICE_DFP1_INDEX ) +#define ATOM_DEVICE_CRT2_SUPPORT (0x1L << ATOM_DEVICE_CRT2_INDEX ) +#define ATOM_DEVICE_LCD2_SUPPORT (0x1L << ATOM_DEVICE_LCD2_INDEX ) +#define ATOM_DEVICE_DFP6_SUPPORT (0x1L << ATOM_DEVICE_DFP6_INDEX ) +#define ATOM_DEVICE_DFP2_SUPPORT (0x1L << ATOM_DEVICE_DFP2_INDEX ) +#define ATOM_DEVICE_CV_SUPPORT (0x1L << ATOM_DEVICE_CV_INDEX ) +#define ATOM_DEVICE_DFP3_SUPPORT (0x1L << ATOM_DEVICE_DFP3_INDEX ) #define ATOM_DEVICE_DFP4_SUPPORT (0x1L << ATOM_DEVICE_DFP4_INDEX ) -#define ATOM_DEVICE_DFP5_SUPPORT (0x1L << ATOM_DEVICE_DFP5_INDEX) +#define ATOM_DEVICE_DFP5_SUPPORT (0x1L << ATOM_DEVICE_DFP5_INDEX ) -#define ATOM_DEVICE_CRT_SUPPORT \ - (ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT) -#define ATOM_DEVICE_DFP_SUPPORT \ - (ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | \ - ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | \ - ATOM_DEVICE_DFP5_SUPPORT) -#define ATOM_DEVICE_TV_SUPPORT \ - (ATOM_DEVICE_TV1_SUPPORT | ATOM_DEVICE_TV2_SUPPORT) -#define ATOM_DEVICE_LCD_SUPPORT \ - (ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT) +#define ATOM_DEVICE_CRT_SUPPORT (ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT) +#define ATOM_DEVICE_DFP_SUPPORT (ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | ATOM_DEVICE_DFP5_SUPPORT | ATOM_DEVICE_DFP6_SUPPORT) +#define ATOM_DEVICE_TV_SUPPORT (ATOM_DEVICE_TV1_SUPPORT) +#define ATOM_DEVICE_LCD_SUPPORT (ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT) #define ATOM_DEVICE_CONNECTOR_TYPE_MASK 0x000000F0 #define ATOM_DEVICE_CONNECTOR_TYPE_SHIFT 0x00000004 @@ -1942,6 +2412,7 @@ usMinDownStreamHTLinkWidth: same as above. #define ATOM_DEVICE_CONNECTOR_CASE_1 0x0000000E #define ATOM_DEVICE_CONNECTOR_DISPLAYPORT 0x0000000F + #define ATOM_DEVICE_DAC_INFO_MASK 0x0000000F #define ATOM_DEVICE_DAC_INFO_SHIFT 0x00000000 #define ATOM_DEVICE_DAC_INFO_NODAC 0x00000000 @@ -1958,41 +2429,45 @@ usMinDownStreamHTLinkWidth: same as above. #define ATOM_DEVICE_I2C_ID_SHIFT 0x00000004 #define ATOM_DEVICE_I2C_ID_IS_FOR_NON_MM_USE 0x00000001 #define ATOM_DEVICE_I2C_ID_IS_FOR_MM_USE 0x00000002 -#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE 0x00000003 /* For IGP RS600 */ -#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL 0x00000004 /* For IGP RS690 */ +#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE 0x00000003 //For IGP RS600 +#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL 0x00000004 //For IGP RS690 #define ATOM_DEVICE_I2C_HARDWARE_CAP_MASK 0x00000080 #define ATOM_DEVICE_I2C_HARDWARE_CAP_SHIFT 0x00000007 #define ATOM_DEVICE_USES_SOFTWARE_ASSISTED_I2C 0x00000000 #define ATOM_DEVICE_USES_HARDWARE_ASSISTED_I2C 0x00000001 -/* usDeviceSupport: */ -/* Bits0 = 0 - no CRT1 support= 1- CRT1 is supported */ -/* Bit 1 = 0 - no LCD1 support= 1- LCD1 is supported */ -/* Bit 2 = 0 - no TV1 support= 1- TV1 is supported */ -/* Bit 3 = 0 - no DFP1 support= 1- DFP1 is supported */ -/* Bit 4 = 0 - no CRT2 support= 1- CRT2 is supported */ -/* Bit 5 = 0 - no LCD2 support= 1- LCD2 is supported */ -/* Bit 6 = 0 - no TV2 support= 1- TV2 is supported */ -/* Bit 7 = 0 - no DFP2 support= 1- DFP2 is supported */ -/* Bit 8 = 0 - no CV support= 1- CV is supported */ -/* Bit 9 = 0 - no DFP3 support= 1- DFP3 is supported */ -/* Byte1 (Supported Device Info) */ -/* Bit 0 = = 0 - no CV support= 1- CV is supported */ -/* */ -/* */ +// usDeviceSupport: +// Bits0 = 0 - no CRT1 support= 1- CRT1 is supported +// Bit 1 = 0 - no LCD1 support= 1- LCD1 is supported +// Bit 2 = 0 - no TV1 support= 1- TV1 is supported +// Bit 3 = 0 - no DFP1 support= 1- DFP1 is supported +// Bit 4 = 0 - no CRT2 support= 1- CRT2 is supported +// Bit 5 = 0 - no LCD2 support= 1- LCD2 is supported +// Bit 6 = 0 - no DFP6 support= 1- DFP6 is supported +// Bit 7 = 0 - no DFP2 support= 1- DFP2 is supported +// Bit 8 = 0 - no CV support= 1- CV is supported +// Bit 9 = 0 - no DFP3 support= 1- DFP3 is supported +// Bit 10 = 0 - no DFP4 support= 1- DFP4 is supported +// Bit 11 = 0 - no DFP5 support= 1- DFP5 is supported +// +// -/* ucI2C_ConfigID */ -/* [7:0] - I2C LINE Associate ID */ -/* = 0 - no I2C */ -/* [7] - HW_Cap = 1, [6:0]=HW assisted I2C ID(HW line selection) */ -/* = 0, [6:0]=SW assisted I2C ID */ -/* [6-4] - HW_ENGINE_ID = 1, HW engine for NON multimedia use */ -/* = 2, HW engine for Multimedia use */ -/* = 3-7 Reserved for future I2C engines */ -/* [3-0] - I2C_LINE_MUX = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C */ +/****************************************************************************/ +/* Structure used in MclkSS_InfoTable */ +/****************************************************************************/ +// ucI2C_ConfigID +// [7:0] - I2C LINE Associate ID +// = 0 - no I2C +// [7] - HW_Cap = 1, [6:0]=HW assisted I2C ID(HW line selection) +// = 0, [6:0]=SW assisted I2C ID +// [6-4] - HW_ENGINE_ID = 1, HW engine for NON multimedia use +// = 2, HW engine for Multimedia use +// = 3-7 Reserved for future I2C engines +// [3-0] - I2C_LINE_MUX = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C -typedef struct _ATOM_I2C_ID_CONFIG { +typedef struct _ATOM_I2C_ID_CONFIG +{ #if ATOM_BIG_ENDIAN UCHAR bfHW_Capable:1; UCHAR bfHW_EngineID:3; @@ -2002,17 +2477,20 @@ typedef struct _ATOM_I2C_ID_CONFIG { UCHAR bfHW_EngineID:3; UCHAR bfHW_Capable:1; #endif -} ATOM_I2C_ID_CONFIG; +}ATOM_I2C_ID_CONFIG; -typedef union _ATOM_I2C_ID_CONFIG_ACCESS { +typedef union _ATOM_I2C_ID_CONFIG_ACCESS +{ ATOM_I2C_ID_CONFIG sbfAccess; UCHAR ucAccess; -} ATOM_I2C_ID_CONFIG_ACCESS; +}ATOM_I2C_ID_CONFIG_ACCESS; + /****************************************************************************/ -/* Structure used in GPIO_I2C_InfoTable */ +// Structure used in GPIO_I2C_InfoTable /****************************************************************************/ -typedef struct _ATOM_GPIO_I2C_ASSIGMENT { +typedef struct _ATOM_GPIO_I2C_ASSIGMENT +{ USHORT usClkMaskRegisterIndex; USHORT usClkEnRegisterIndex; USHORT usClkY_RegisterIndex; @@ -2032,21 +2510,23 @@ typedef struct _ATOM_GPIO_I2C_ASSIGMENT { UCHAR ucDataA_Shift; UCHAR ucReserved1; UCHAR ucReserved2; -} ATOM_GPIO_I2C_ASSIGMENT; +}ATOM_GPIO_I2C_ASSIGMENT; -typedef struct _ATOM_GPIO_I2C_INFO { +typedef struct _ATOM_GPIO_I2C_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_GPIO_I2C_ASSIGMENT asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE]; -} ATOM_GPIO_I2C_INFO; +}ATOM_GPIO_I2C_INFO; /****************************************************************************/ -/* Common Structure used in other structures */ +// Common Structure used in other structures /****************************************************************************/ #ifndef _H2INC -/* Please don't add or expand this bitfield structure below, this one will retire soon.! */ -typedef struct _ATOM_MODE_MISC_INFO { +//Please don't add or expand this bitfield structure below, this one will retire soon.! +typedef struct _ATOM_MODE_MISC_INFO +{ #if ATOM_BIG_ENDIAN USHORT Reserved:6; USHORT RGB888:1; @@ -2056,13 +2536,13 @@ typedef struct _ATOM_MODE_MISC_INFO { USHORT V_ReplicationBy2:1; USHORT H_ReplicationBy2:1; USHORT VerticalCutOff:1; - USHORT VSyncPolarity:1; /* 0=Active High, 1=Active Low */ - USHORT HSyncPolarity:1; /* 0=Active High, 1=Active Low */ + USHORT VSyncPolarity:1; //0=Active High, 1=Active Low + USHORT HSyncPolarity:1; //0=Active High, 1=Active Low USHORT HorizontalCutOff:1; #else USHORT HorizontalCutOff:1; - USHORT HSyncPolarity:1; /* 0=Active High, 1=Active Low */ - USHORT VSyncPolarity:1; /* 0=Active High, 1=Active Low */ + USHORT HSyncPolarity:1; //0=Active High, 1=Active Low + USHORT VSyncPolarity:1; //0=Active High, 1=Active Low USHORT VerticalCutOff:1; USHORT H_ReplicationBy2:1; USHORT V_ReplicationBy2:1; @@ -2072,25 +2552,27 @@ typedef struct _ATOM_MODE_MISC_INFO { USHORT RGB888:1; USHORT Reserved:6; #endif -} ATOM_MODE_MISC_INFO; +}ATOM_MODE_MISC_INFO; -typedef union _ATOM_MODE_MISC_INFO_ACCESS { +typedef union _ATOM_MODE_MISC_INFO_ACCESS +{ ATOM_MODE_MISC_INFO sbfAccess; USHORT usAccess; -} ATOM_MODE_MISC_INFO_ACCESS; +}ATOM_MODE_MISC_INFO_ACCESS; #else -typedef union _ATOM_MODE_MISC_INFO_ACCESS { +typedef union _ATOM_MODE_MISC_INFO_ACCESS +{ USHORT usAccess; -} ATOM_MODE_MISC_INFO_ACCESS; +}ATOM_MODE_MISC_INFO_ACCESS; #endif -/* usModeMiscInfo- */ +// usModeMiscInfo- #define ATOM_H_CUTOFF 0x01 -#define ATOM_HSYNC_POLARITY 0x02 /* 0=Active High, 1=Active Low */ -#define ATOM_VSYNC_POLARITY 0x04 /* 0=Active High, 1=Active Low */ +#define ATOM_HSYNC_POLARITY 0x02 //0=Active High, 1=Active Low +#define ATOM_VSYNC_POLARITY 0x04 //0=Active High, 1=Active Low #define ATOM_V_CUTOFF 0x08 #define ATOM_H_REPLICATIONBY2 0x10 #define ATOM_V_REPLICATIONBY2 0x20 @@ -2099,7 +2581,7 @@ typedef union _ATOM_MODE_MISC_INFO_ACCESS { #define ATOM_DOUBLE_CLOCK_MODE 0x100 #define ATOM_RGB888_MODE 0x200 -/* usRefreshRate- */ +//usRefreshRate- #define ATOM_REFRESH_43 43 #define ATOM_REFRESH_47 47 #define ATOM_REFRESH_56 56 @@ -2110,21 +2592,22 @@ typedef union _ATOM_MODE_MISC_INFO_ACCESS { #define ATOM_REFRESH_75 75 #define ATOM_REFRESH_85 85 -/* ATOM_MODE_TIMING data are exactly the same as VESA timing data. */ -/* Translation from EDID to ATOM_MODE_TIMING, use the following formula. */ -/* */ -/* VESA_HTOTAL = VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK */ -/* = EDID_HA + EDID_HBL */ -/* VESA_HDISP = VESA_ACTIVE = EDID_HA */ -/* VESA_HSYNC_START = VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH */ -/* = EDID_HA + EDID_HSO */ -/* VESA_HSYNC_WIDTH = VESA_HSYNC_TIME = EDID_HSPW */ -/* VESA_BORDER = EDID_BORDER */ +// ATOM_MODE_TIMING data are exactly the same as VESA timing data. +// Translation from EDID to ATOM_MODE_TIMING, use the following formula. +// +// VESA_HTOTAL = VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK +// = EDID_HA + EDID_HBL +// VESA_HDISP = VESA_ACTIVE = EDID_HA +// VESA_HSYNC_START = VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH +// = EDID_HA + EDID_HSO +// VESA_HSYNC_WIDTH = VESA_HSYNC_TIME = EDID_HSPW +// VESA_BORDER = EDID_BORDER /****************************************************************************/ -/* Structure used in SetCRTC_UsingDTDTimingTable */ +// Structure used in SetCRTC_UsingDTDTimingTable /****************************************************************************/ -typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS { +typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS +{ USHORT usH_Size; USHORT usH_Blanking_Time; USHORT usV_Size; @@ -2134,40 +2617,42 @@ typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS { USHORT usV_SyncOffset; USHORT usV_SyncWidth; ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - UCHAR ucH_Border; /* From DFP EDID */ + UCHAR ucH_Border; // From DFP EDID UCHAR ucV_Border; - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 UCHAR ucPadding[3]; -} SET_CRTC_USING_DTD_TIMING_PARAMETERS; +}SET_CRTC_USING_DTD_TIMING_PARAMETERS; /****************************************************************************/ -/* Structure used in SetCRTC_TimingTable */ +// Structure used in SetCRTC_TimingTable /****************************************************************************/ -typedef struct _SET_CRTC_TIMING_PARAMETERS { - USHORT usH_Total; /* horizontal total */ - USHORT usH_Disp; /* horizontal display */ - USHORT usH_SyncStart; /* horozontal Sync start */ - USHORT usH_SyncWidth; /* horizontal Sync width */ - USHORT usV_Total; /* vertical total */ - USHORT usV_Disp; /* vertical display */ - USHORT usV_SyncStart; /* vertical Sync start */ - USHORT usV_SyncWidth; /* vertical Sync width */ +typedef struct _SET_CRTC_TIMING_PARAMETERS +{ + USHORT usH_Total; // horizontal total + USHORT usH_Disp; // horizontal display + USHORT usH_SyncStart; // horozontal Sync start + USHORT usH_SyncWidth; // horizontal Sync width + USHORT usV_Total; // vertical total + USHORT usV_Disp; // vertical display + USHORT usV_SyncStart; // vertical Sync start + USHORT usV_SyncWidth; // vertical Sync width ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - UCHAR ucCRTC; /* ATOM_CRTC1 or ATOM_CRTC2 */ - UCHAR ucOverscanRight; /* right */ - UCHAR ucOverscanLeft; /* left */ - UCHAR ucOverscanBottom; /* bottom */ - UCHAR ucOverscanTop; /* top */ + UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 + UCHAR ucOverscanRight; // right + UCHAR ucOverscanLeft; // left + UCHAR ucOverscanBottom; // bottom + UCHAR ucOverscanTop; // top UCHAR ucReserved; -} SET_CRTC_TIMING_PARAMETERS; +}SET_CRTC_TIMING_PARAMETERS; #define SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION SET_CRTC_TIMING_PARAMETERS /****************************************************************************/ -/* Structure used in StandardVESA_TimingTable */ -/* AnalogTV_InfoTable */ -/* ComponentVideoInfoTable */ +// Structure used in StandardVESA_TimingTable +// AnalogTV_InfoTable +// ComponentVideoInfoTable /****************************************************************************/ -typedef struct _ATOM_MODE_TIMING { +typedef struct _ATOM_MODE_TIMING +{ USHORT usCRTC_H_Total; USHORT usCRTC_H_Disp; USHORT usCRTC_H_SyncStart; @@ -2176,7 +2661,7 @@ typedef struct _ATOM_MODE_TIMING { USHORT usCRTC_V_Disp; USHORT usCRTC_V_SyncStart; USHORT usCRTC_V_SyncWidth; - USHORT usPixelClock; /* in 10Khz unit */ + USHORT usPixelClock; //in 10Khz unit ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; USHORT usCRTC_OverscanRight; USHORT usCRTC_OverscanLeft; @@ -2185,9 +2670,10 @@ typedef struct _ATOM_MODE_TIMING { USHORT usReserve; UCHAR ucInternalModeNumber; UCHAR ucRefreshRate; -} ATOM_MODE_TIMING; +}ATOM_MODE_TIMING; -typedef struct _ATOM_DTD_FORMAT { +typedef struct _ATOM_DTD_FORMAT +{ USHORT usPixClk; USHORT usHActive; USHORT usHBlanking_Time; @@ -2204,98 +2690,135 @@ typedef struct _ATOM_DTD_FORMAT { ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; UCHAR ucInternalModeNumber; UCHAR ucRefreshRate; -} ATOM_DTD_FORMAT; +}ATOM_DTD_FORMAT; /****************************************************************************/ -/* Structure used in LVDS_InfoTable */ -/* * Need a document to describe this table */ +// Structure used in LVDS_InfoTable +// * Need a document to describe this table /****************************************************************************/ #define SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 #define SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 #define SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 #define SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 -/* Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. */ -/* Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL */ -#define LCDPANEL_CAP_READ_EDID 0x1 - -/* ucTableFormatRevision=1 */ -/* ucTableContentRevision=1 */ -typedef struct _ATOM_LVDS_INFO { +//ucTableFormatRevision=1 +//ucTableContentRevision=1 +typedef struct _ATOM_LVDS_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_DTD_FORMAT sLCDTiming; USHORT usModePatchTableOffset; - USHORT usSupportedRefreshRate; /* Refer to panel info table in ATOMBIOS extension Spec. */ + USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. USHORT usOffDelayInMs; UCHAR ucPowerSequenceDigOntoDEin10Ms; UCHAR ucPowerSequenceDEtoBLOnin10Ms; - UCHAR ucLVDS_Misc; /* Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} */ - /* Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} */ - /* Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} */ - /* Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} */ + UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} + // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} + // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} + // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} UCHAR ucPanelDefaultRefreshRate; UCHAR ucPanelIdentification; UCHAR ucSS_Id; -} ATOM_LVDS_INFO; +}ATOM_LVDS_INFO; -/* ucTableFormatRevision=1 */ -/* ucTableContentRevision=2 */ -typedef struct _ATOM_LVDS_INFO_V12 { +//ucTableFormatRevision=1 +//ucTableContentRevision=2 +typedef struct _ATOM_LVDS_INFO_V12 +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_DTD_FORMAT sLCDTiming; USHORT usExtInfoTableOffset; - USHORT usSupportedRefreshRate; /* Refer to panel info table in ATOMBIOS extension Spec. */ + USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. USHORT usOffDelayInMs; UCHAR ucPowerSequenceDigOntoDEin10Ms; UCHAR ucPowerSequenceDEtoBLOnin10Ms; - UCHAR ucLVDS_Misc; /* Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} */ - /* Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} */ - /* Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} */ - /* Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} */ + UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} + // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} + // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} + // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} UCHAR ucPanelDefaultRefreshRate; UCHAR ucPanelIdentification; UCHAR ucSS_Id; USHORT usLCDVenderID; USHORT usLCDProductID; UCHAR ucLCDPanel_SpecialHandlingCap; - UCHAR ucPanelInfoSize; /* start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable */ + UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable UCHAR ucReserved[2]; -} ATOM_LVDS_INFO_V12; +}ATOM_LVDS_INFO_V12; + +//Definitions for ucLCDPanel_SpecialHandlingCap: + +//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. +//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL +#define LCDPANEL_CAP_READ_EDID 0x1 + +//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together +//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static +//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12 +#define LCDPANEL_CAP_DRR_SUPPORTED 0x2 + +//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. +#define LCDPANEL_CAP_eDP 0x4 + + +//Color Bit Depth definition in EDID V1.4 @BYTE 14h +//Bit 6 5 4 + // 0 0 0 - Color bit depth is undefined + // 0 0 1 - 6 Bits per Primary Color + // 0 1 0 - 8 Bits per Primary Color + // 0 1 1 - 10 Bits per Primary Color + // 1 0 0 - 12 Bits per Primary Color + // 1 0 1 - 14 Bits per Primary Color + // 1 1 0 - 16 Bits per Primary Color + // 1 1 1 - Reserved + +#define PANEL_COLOR_BIT_DEPTH_MASK 0x70 + +// Bit7:{=0:Random Dithering disabled;1 Random Dithering enabled} +#define PANEL_RANDOM_DITHER 0x80 +#define PANEL_RANDOM_DITHER_MASK 0x80 + #define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 -typedef struct _ATOM_PATCH_RECORD_MODE { +typedef struct _ATOM_PATCH_RECORD_MODE +{ UCHAR ucRecordType; USHORT usHDisp; USHORT usVDisp; -} ATOM_PATCH_RECORD_MODE; +}ATOM_PATCH_RECORD_MODE; -typedef struct _ATOM_LCD_RTS_RECORD { +typedef struct _ATOM_LCD_RTS_RECORD +{ UCHAR ucRecordType; UCHAR ucRTSValue; -} ATOM_LCD_RTS_RECORD; +}ATOM_LCD_RTS_RECORD; -/* !! If the record below exits, it shoud always be the first record for easy use in command table!!! */ -typedef struct _ATOM_LCD_MODE_CONTROL_CAP { +//!! If the record below exits, it shoud always be the first record for easy use in command table!!! +// The record below is only used when LVDS_Info is present. From ATOM_LVDS_INFO_V12, use ucLCDPanel_SpecialHandlingCap instead. +typedef struct _ATOM_LCD_MODE_CONTROL_CAP +{ UCHAR ucRecordType; USHORT usLCDCap; -} ATOM_LCD_MODE_CONTROL_CAP; +}ATOM_LCD_MODE_CONTROL_CAP; #define LCD_MODE_CAP_BL_OFF 1 #define LCD_MODE_CAP_CRTC_OFF 2 #define LCD_MODE_CAP_PANEL_OFF 4 -typedef struct _ATOM_FAKE_EDID_PATCH_RECORD { +typedef struct _ATOM_FAKE_EDID_PATCH_RECORD +{ UCHAR ucRecordType; UCHAR ucFakeEDIDLength; - UCHAR ucFakeEDIDString[1]; /* This actually has ucFakeEdidLength elements. */ + UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. } ATOM_FAKE_EDID_PATCH_RECORD; -typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD { +typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD +{ UCHAR ucRecordType; USHORT usHSize; USHORT usVSize; -} ATOM_PANEL_RESOLUTION_PATCH_RECORD; +}ATOM_PANEL_RESOLUTION_PATCH_RECORD; #define LCD_MODE_PATCH_RECORD_MODE_TYPE 1 #define LCD_RTS_RECORD_TYPE 2 @@ -2306,21 +2829,25 @@ typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD { /****************************Spread Spectrum Info Table Definitions **********************/ -/* ucTableFormatRevision=1 */ -/* ucTableContentRevision=2 */ -typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT { +//ucTableFormatRevision=1 +//ucTableContentRevision=2 +typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT +{ USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; /* Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD */ + UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Bit2=1: PCIE REFCLK SS =0 iternal PPLL SS Others:TBD UCHAR ucSS_Step; UCHAR ucSS_Delay; UCHAR ucSS_Id; UCHAR ucRecommendedRef_Div; - UCHAR ucSS_Range; /* it was reserved for V11 */ -} ATOM_SPREAD_SPECTRUM_ASSIGNMENT; + UCHAR ucSS_Range; //it was reserved for V11 +}ATOM_SPREAD_SPECTRUM_ASSIGNMENT; #define ATOM_MAX_SS_ENTRY 16 -#define ATOM_DP_SS_ID1 0x0f1 /* SS modulation freq=30k */ -#define ATOM_DP_SS_ID2 0x0f2 /* SS modulation freq=33k */ +#define ATOM_DP_SS_ID1 0x0f1 // SS ID for internal DP stream at 2.7Ghz. if ATOM_DP_SS_ID2 does not exist in SS_InfoTable, it is used for internal DP stream at 1.62Ghz as well. +#define ATOM_DP_SS_ID2 0x0f2 // SS ID for internal DP stream at 1.62Ghz, if it exists in SS_InfoTable. +#define ATOM_LVLINK_2700MHz_SS_ID 0x0f3 // SS ID for LV link translator chip at 2.7Ghz +#define ATOM_LVLINK_1620MHz_SS_ID 0x0f4 // SS ID for LV link translator chip at 1.62Ghz + #define ATOM_SS_DOWN_SPREAD_MODE_MASK 0x00000000 #define ATOM_SS_DOWN_SPREAD_MODE 0x00000000 @@ -2332,26 +2859,27 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT { #define EXEC_SS_DELAY_SHIFT 4 #define ACTIVEDATA_TO_BLON_DELAY_SHIFT 4 -typedef struct _ATOM_SPREAD_SPECTRUM_INFO { +typedef struct _ATOM_SPREAD_SPECTRUM_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_SPREAD_SPECTRUM_ASSIGNMENT asSS_Info[ATOM_MAX_SS_ENTRY]; -} ATOM_SPREAD_SPECTRUM_INFO; +}ATOM_SPREAD_SPECTRUM_INFO; /****************************************************************************/ -/* Structure used in AnalogTV_InfoTable (Top level) */ +// Structure used in AnalogTV_InfoTable (Top level) /****************************************************************************/ -/* ucTVBootUpDefaultStd definiton: */ +//ucTVBootUpDefaultStd definiton: -/* ATOM_TV_NTSC 1 */ -/* ATOM_TV_NTSCJ 2 */ -/* ATOM_TV_PAL 3 */ -/* ATOM_TV_PALM 4 */ -/* ATOM_TV_PALCN 5 */ -/* ATOM_TV_PALN 6 */ -/* ATOM_TV_PAL60 7 */ -/* ATOM_TV_SECAM 8 */ +//ATOM_TV_NTSC 1 +//ATOM_TV_NTSCJ 2 +//ATOM_TV_PAL 3 +//ATOM_TV_PALM 4 +//ATOM_TV_PALCN 5 +//ATOM_TV_PALN 6 +//ATOM_TV_PAL60 7 +//ATOM_TV_SECAM 8 -/* ucTVSuppportedStd definition: */ +//ucTVSupportedStd definition: #define NTSC_SUPPORT 0x1 #define NTSCJ_SUPPORT 0x2 @@ -2364,46 +2892,58 @@ typedef struct _ATOM_SPREAD_SPECTRUM_INFO { #define MAX_SUPPORTED_TV_TIMING 2 -typedef struct _ATOM_ANALOG_TV_INFO { +typedef struct _ATOM_ANALOG_TV_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucTV_SupportedStandard; UCHAR ucTV_BootUpDefaultStandard; UCHAR ucExt_TV_ASIC_ID; UCHAR ucExt_TV_ASIC_SlaveAddr; - /*ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; */ + /*ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING];*/ ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; -} ATOM_ANALOG_TV_INFO; +}ATOM_ANALOG_TV_INFO; #define MAX_SUPPORTED_TV_TIMING_V1_2 3 -typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { +typedef struct _ATOM_ANALOG_TV_INFO_V1_2 +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucTV_SupportedStandard; UCHAR ucTV_BootUpDefaultStandard; UCHAR ucExt_TV_ASIC_ID; UCHAR ucExt_TV_ASIC_SlaveAddr; ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; -} ATOM_ANALOG_TV_INFO_V1_2; +}ATOM_ANALOG_TV_INFO_V1_2; + +typedef struct _ATOM_DPCD_INFO +{ + UCHAR ucRevisionNumber; //10h : Revision 1.0; 11h : Revision 1.1 + UCHAR ucMaxLinkRate; //06h : 1.62Gbps per lane; 0Ah = 2.7Gbps per lane + UCHAR ucMaxLane; //Bits 4:0 = MAX_LANE_COUNT (1/2/4). Bit 7 = ENHANCED_FRAME_CAP + UCHAR ucMaxDownSpread; //Bit0 = 0: No Down spread; Bit0 = 1: 0.5% (Subject to change according to DP spec) +}ATOM_DPCD_INFO; + +#define ATOM_DPCD_MAX_LANE_MASK 0x1F /**************************************************************************/ -/* VRAM usage and their definitions */ +// VRAM usage and their defintions -/* One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */ -/* Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */ -/* All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned! */ -/* To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR */ -/* To Bios: ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX */ +// One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. +// Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. +// All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned! +// To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR +// To Bios: ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX #ifndef VESA_MEMORY_IN_64K_BLOCK -#define VESA_MEMORY_IN_64K_BLOCK 0x100 /* 256*64K=16Mb (Max. VESA memory is 16Mb!) */ +#define VESA_MEMORY_IN_64K_BLOCK 0x100 //256*64K=16Mb (Max. VESA memory is 16Mb!) #endif -#define ATOM_EDID_RAW_DATASIZE 256 /* In Bytes */ -#define ATOM_HWICON_SURFACE_SIZE 4096 /* In Bytes */ +#define ATOM_EDID_RAW_DATASIZE 256 //In Bytes +#define ATOM_HWICON_SURFACE_SIZE 4096 //In Bytes #define ATOM_HWICON_INFOTABLE_SIZE 32 #define MAX_DTD_MODE_IN_VRAM 6 -#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) /* 28= (SIZEOF ATOM_DTD_FORMAT) */ -#define ATOM_STD_MODE_SUPPORT_TBL_SIZE (32*8) /* 32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) */ +#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) +#define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) #define DFP_ENCODER_TYPE_OFFSET 0x80 #define DP_ENCODER_LANE_NUM_OFFSET 0x84 #define DP_ENCODER_LINK_RATE_OFFSET 0x88 @@ -2433,11 +2973,11 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { #define ATOM_LCD2_DTD_MODE_TBL_ADDR (ATOM_LCD2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) #define ATOM_LCD2_STD_MODE_TBL_ADDR (ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_TV2_EDID_ADDR (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_TV2_DTD_MODE_TBL_ADDR (ATOM_TV2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_TV2_STD_MODE_TBL_ADDR (ATOM_TV2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) +#define ATOM_DFP6_EDID_ADDR (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) +#define ATOM_DFP6_DTD_MODE_TBL_ADDR (ATOM_DFP6_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) +#define ATOM_DFP6_STD_MODE_TBL_ADDR (ATOM_DFP6_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP2_EDID_ADDR (ATOM_TV2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) +#define ATOM_DFP2_EDID_ADDR (ATOM_DFP6_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) #define ATOM_DFP2_DTD_MODE_TBL_ADDR (ATOM_DFP2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) #define ATOM_DFP2_STD_MODE_TBL_ADDR (ATOM_DFP2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) @@ -2459,10 +2999,10 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { #define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR + 256) -#define ATOM_STACK_STORAGE_END (ATOM_STACK_STORAGE_START + 512) +#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR+256) +#define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START+512 -/* The size below is in Kb! */ +//The size below is in Kb! #define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) #define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L @@ -2471,100 +3011,135 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { #define ATOM_VRAM_BLOCK_NEEDS_RESERVATION 0x0 /***********************************************************************************/ -/* Structure used in VRAM_UsageByFirmwareTable */ -/* Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm */ -/* at running time. */ -/* note2: From RV770, the memory is more than 32bit addressable, so we will change */ -/* ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains */ -/* exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware */ -/* (in offset to start of memory address) is KB aligned instead of byte aligend. */ +// Structure used in VRAM_UsageByFirmwareTable +// Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm +// at running time. +// note2: From RV770, the memory is more than 32bit addressable, so we will change +// ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains +// exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware +// (in offset to start of memory address) is KB aligned instead of byte aligend. /***********************************************************************************/ +// Note3: +/* If we change usReserved to "usFBUsedbyDrvInKB", then to VBIOS this usFBUsedbyDrvInKB is a predefined, unchanged constant across VGA or non VGA adapter, +for CAIL, The size of FB access area is known, only thing missing is the Offset of FB Access area, so we can have: + +If (ulStartAddrUsedByFirmware!=0) +FBAccessAreaOffset= ulStartAddrUsedByFirmware - usFBUsedbyDrvInKB; +Reserved area has been claimed by VBIOS including this FB access area; CAIL doesn't need to reserve any extra area for this purpose +else //Non VGA case + if (FB_Size<=2Gb) + FBAccessAreaOffset= FB_Size - usFBUsedbyDrvInKB; + else + FBAccessAreaOffset= Aper_Size - usFBUsedbyDrvInKB + +CAIL needs to claim an reserved area defined by FBAccessAreaOffset and usFBUsedbyDrvInKB in non VGA case.*/ + #define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO 1 -typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO { +typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO +{ ULONG ulStartAddrUsedByFirmware; USHORT usFirmwareUseInKb; USHORT usReserved; -} ATOM_FIRMWARE_VRAM_RESERVE_INFO; +}ATOM_FIRMWARE_VRAM_RESERVE_INFO; -typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE { +typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_FIRMWARE_VRAM_RESERVE_INFO asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; +}ATOM_VRAM_USAGE_BY_FIRMWARE; + +// change verion to 1.5, when allow driver to allocate the vram area for command table access. +typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5 +{ + ULONG ulStartAddrUsedByFirmware; + USHORT usFirmwareUseInKb; + USHORT usFBUsedByDrvInKb; +}ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5; + +typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5 +{ ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_FIRMWARE_VRAM_RESERVE_INFO - asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; -} ATOM_VRAM_USAGE_BY_FIRMWARE; + ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5 asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; +}ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5; /****************************************************************************/ -/* Structure used in GPIO_Pin_LUTTable */ +// Structure used in GPIO_Pin_LUTTable /****************************************************************************/ -typedef struct _ATOM_GPIO_PIN_ASSIGNMENT { +typedef struct _ATOM_GPIO_PIN_ASSIGNMENT +{ USHORT usGpioPin_AIndex; UCHAR ucGpioPinBitShift; UCHAR ucGPIO_ID; -} ATOM_GPIO_PIN_ASSIGNMENT; +}ATOM_GPIO_PIN_ASSIGNMENT; -typedef struct _ATOM_GPIO_PIN_LUT { +typedef struct _ATOM_GPIO_PIN_LUT +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1]; -} ATOM_GPIO_PIN_LUT; +}ATOM_GPIO_PIN_LUT; /****************************************************************************/ -/* Structure used in ComponentVideoInfoTable */ +// Structure used in ComponentVideoInfoTable /****************************************************************************/ #define GPIO_PIN_ACTIVE_HIGH 0x1 #define MAX_SUPPORTED_CV_STANDARDS 5 -/* definitions for ATOM_D_INFO.ucSettings */ -#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK 0x1F /* [4:0] */ -#define ATOM_GPIO_SETTINGS_RESERVED_MASK 0x60 /* [6:5] = must be zeroed out */ -#define ATOM_GPIO_SETTINGS_ACTIVE_MASK 0x80 /* [7] */ +// definitions for ATOM_D_INFO.ucSettings +#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK 0x1F // [4:0] +#define ATOM_GPIO_SETTINGS_RESERVED_MASK 0x60 // [6:5] = must be zeroed out +#define ATOM_GPIO_SETTINGS_ACTIVE_MASK 0x80 // [7] -typedef struct _ATOM_GPIO_INFO { +typedef struct _ATOM_GPIO_INFO +{ USHORT usAOffset; UCHAR ucSettings; UCHAR ucReserved; -} ATOM_GPIO_INFO; +}ATOM_GPIO_INFO; -/* definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector) */ +// definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector) #define ATOM_CV_RESTRICT_FORMAT_SELECTION 0x2 -/* definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i */ -#define ATOM_GPIO_DEFAULT_MODE_EN 0x80 /* [7]; */ -#define ATOM_GPIO_SETTING_PERMODE_MASK 0x7F /* [6:0] */ +// definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i +#define ATOM_GPIO_DEFAULT_MODE_EN 0x80 //[7]; +#define ATOM_GPIO_SETTING_PERMODE_MASK 0x7F //[6:0] -/* definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode */ -/* Line 3 out put 5V. */ -#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A 0x01 /* represent gpio 3 state for 16:9 */ -#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B 0x02 /* represent gpio 4 state for 16:9 */ +// definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode +//Line 3 out put 5V. +#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A 0x01 //represent gpio 3 state for 16:9 +#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B 0x02 //represent gpio 4 state for 16:9 #define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT 0x0 -/* Line 3 out put 2.2V */ -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04 /* represent gpio 3 state for 4:3 Letter box */ -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08 /* represent gpio 4 state for 4:3 Letter box */ +//Line 3 out put 2.2V +#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04 //represent gpio 3 state for 4:3 Letter box +#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08 //represent gpio 4 state for 4:3 Letter box #define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2 -/* Line 3 out put 0V */ -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A 0x10 /* represent gpio 3 state for 4:3 */ -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B 0x20 /* represent gpio 4 state for 4:3 */ +//Line 3 out put 0V +#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A 0x10 //represent gpio 3 state for 4:3 +#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B 0x20 //represent gpio 4 state for 4:3 #define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT 0x4 -#define ATOM_CV_LINE3_ASPECTRATIO_MASK 0x3F /* bit [5:0] */ +#define ATOM_CV_LINE3_ASPECTRATIO_MASK 0x3F // bit [5:0] -#define ATOM_CV_LINE3_ASPECTRATIO_EXIST 0x80 /* bit 7 */ +#define ATOM_CV_LINE3_ASPECTRATIO_EXIST 0x80 //bit 7 -/* GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks. */ -#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A 3 /* bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. */ -#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B 4 /* bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. */ +//GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks. +#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A 3 //bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. +#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B 4 //bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. -typedef struct _ATOM_COMPONENT_VIDEO_INFO { + +typedef struct _ATOM_COMPONENT_VIDEO_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usMask_PinRegisterIndex; USHORT usEN_PinRegisterIndex; USHORT usY_PinRegisterIndex; USHORT usA_PinRegisterIndex; UCHAR ucBitShift; - UCHAR ucPinActiveState; /* ucPinActiveState: Bit0=1 active high, =0 active low */ - ATOM_DTD_FORMAT sReserved; /* must be zeroed out */ + UCHAR ucPinActiveState; //ucPinActiveState: Bit0=1 active high, =0 active low + ATOM_DTD_FORMAT sReserved; // must be zeroed out UCHAR ucMiscInfo; UCHAR uc480i; UCHAR uc480p; @@ -2572,14 +3147,15 @@ typedef struct _ATOM_COMPONENT_VIDEO_INFO { UCHAR uc1080i; UCHAR ucLetterBoxMode; UCHAR ucReserved[3]; - UCHAR ucNumOfWbGpioBlocks; /* For Component video D-Connector support. If zere, NTSC type connector */ + UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; -} ATOM_COMPONENT_VIDEO_INFO; +}ATOM_COMPONENT_VIDEO_INFO; -/* ucTableFormatRevision=2 */ -/* ucTableContentRevision=1 */ -typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 { +//ucTableFormatRevision=2 +//ucTableContentRevision=1 +typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucMiscInfo; UCHAR uc480i; @@ -2588,78 +3164,142 @@ typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 { UCHAR uc1080i; UCHAR ucReserved; UCHAR ucLetterBoxMode; - UCHAR ucNumOfWbGpioBlocks; /* For Component video D-Connector support. If zere, NTSC type connector */ + UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; -} ATOM_COMPONENT_VIDEO_INFO_V21; +}ATOM_COMPONENT_VIDEO_INFO_V21; #define ATOM_COMPONENT_VIDEO_INFO_LAST ATOM_COMPONENT_VIDEO_INFO_V21 /****************************************************************************/ -/* Structure used in object_InfoTable */ +// Structure used in object_InfoTable /****************************************************************************/ -typedef struct _ATOM_OBJECT_HEADER { +typedef struct _ATOM_OBJECT_HEADER +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usDeviceSupport; USHORT usConnectorObjectTableOffset; USHORT usRouterObjectTableOffset; USHORT usEncoderObjectTableOffset; - USHORT usProtectionObjectTableOffset; /* only available when Protection block is independent. */ + USHORT usProtectionObjectTableOffset; //only available when Protection block is independent. USHORT usDisplayPathTableOffset; -} ATOM_OBJECT_HEADER; +}ATOM_OBJECT_HEADER; -typedef struct _ATOM_DISPLAY_OBJECT_PATH { - USHORT usDeviceTag; /* supported device */ - USHORT usSize; /* the size of ATOM_DISPLAY_OBJECT_PATH */ - USHORT usConnObjectId; /* Connector Object ID */ - USHORT usGPUObjectId; /* GPU ID */ - USHORT usGraphicObjIds[1]; /* 1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. */ -} ATOM_DISPLAY_OBJECT_PATH; +typedef struct _ATOM_OBJECT_HEADER_V3 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + USHORT usDeviceSupport; + USHORT usConnectorObjectTableOffset; + USHORT usRouterObjectTableOffset; + USHORT usEncoderObjectTableOffset; + USHORT usProtectionObjectTableOffset; //only available when Protection block is independent. + USHORT usDisplayPathTableOffset; + USHORT usMiscObjectTableOffset; +}ATOM_OBJECT_HEADER_V3; -typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE { +typedef struct _ATOM_DISPLAY_OBJECT_PATH +{ + USHORT usDeviceTag; //supported device + USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH + USHORT usConnObjectId; //Connector Object ID + USHORT usGPUObjectId; //GPU ID + USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. +}ATOM_DISPLAY_OBJECT_PATH; + +typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE +{ UCHAR ucNumOfDispPath; UCHAR ucVersion; UCHAR ucPadding[2]; ATOM_DISPLAY_OBJECT_PATH asDispPath[1]; -} ATOM_DISPLAY_OBJECT_PATH_TABLE; +}ATOM_DISPLAY_OBJECT_PATH_TABLE; -typedef struct _ATOM_OBJECT /* each object has this structure */ + +typedef struct _ATOM_OBJECT //each object has this structure { USHORT usObjectID; USHORT usSrcDstTableOffset; - USHORT usRecordOffset; /* this pointing to a bunch of records defined below */ + USHORT usRecordOffset; //this pointing to a bunch of records defined below USHORT usReserved; -} ATOM_OBJECT; +}ATOM_OBJECT; -typedef struct _ATOM_OBJECT_TABLE /* Above 4 object table offset pointing to a bunch of objects all have this structure */ +typedef struct _ATOM_OBJECT_TABLE //Above 4 object table offset pointing to a bunch of objects all have this structure { UCHAR ucNumberOfObjects; UCHAR ucPadding[3]; ATOM_OBJECT asObjects[1]; -} ATOM_OBJECT_TABLE; +}ATOM_OBJECT_TABLE; -typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT /* usSrcDstTableOffset pointing to this structure */ +typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure { UCHAR ucNumberOfSrc; USHORT usSrcObjectID[1]; UCHAR ucNumberOfDst; USHORT usDstObjectID[1]; -} ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; +}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; + + +//Two definitions below are for OPM on MXM module designs + +#define EXT_HPDPIN_LUTINDEX_0 0 +#define EXT_HPDPIN_LUTINDEX_1 1 +#define EXT_HPDPIN_LUTINDEX_2 2 +#define EXT_HPDPIN_LUTINDEX_3 3 +#define EXT_HPDPIN_LUTINDEX_4 4 +#define EXT_HPDPIN_LUTINDEX_5 5 +#define EXT_HPDPIN_LUTINDEX_6 6 +#define EXT_HPDPIN_LUTINDEX_7 7 +#define MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES (EXT_HPDPIN_LUTINDEX_7+1) + +#define EXT_AUXDDC_LUTINDEX_0 0 +#define EXT_AUXDDC_LUTINDEX_1 1 +#define EXT_AUXDDC_LUTINDEX_2 2 +#define EXT_AUXDDC_LUTINDEX_3 3 +#define EXT_AUXDDC_LUTINDEX_4 4 +#define EXT_AUXDDC_LUTINDEX_5 5 +#define EXT_AUXDDC_LUTINDEX_6 6 +#define EXT_AUXDDC_LUTINDEX_7 7 +#define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES (EXT_AUXDDC_LUTINDEX_7+1) + +typedef struct _EXT_DISPLAY_PATH +{ + USHORT usDeviceTag; //A bit vector to show what devices are supported + USHORT usDeviceACPIEnum; //16bit device ACPI id. + USHORT usDeviceConnector; //A physical connector for displays to plug in, using object connector definitions + UCHAR ucExtAUXDDCLutIndex; //An index into external AUX/DDC channel LUT + UCHAR ucExtHPDPINLutIndex; //An index into external HPD pin LUT + USHORT usExtEncoderObjId; //external encoder object id + USHORT usReserved[3]; +}EXT_DISPLAY_PATH; + +#define NUMBER_OF_UCHAR_FOR_GUID 16 +#define MAX_NUMBER_OF_EXT_DISPLAY_PATH 7 + +typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO +{ + ATOM_COMMON_TABLE_HEADER sHeader; + UCHAR ucGuid [NUMBER_OF_UCHAR_FOR_GUID]; // a GUID is a 16 byte long string + EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. + UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. + UCHAR Reserved [7]; // for potential expansion +}ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; + +//Related definitions, all records are differnt but they have a commond header +typedef struct _ATOM_COMMON_RECORD_HEADER +{ + UCHAR ucRecordType; //An emun to indicate the record type + UCHAR ucRecordSize; //The size of the whole record in byte +}ATOM_COMMON_RECORD_HEADER; -/* Related definitions, all records are differnt but they have a commond header */ -typedef struct _ATOM_COMMON_RECORD_HEADER { - UCHAR ucRecordType; /* An emun to indicate the record type */ - UCHAR ucRecordSize; /* The size of the whole record in byte */ -} ATOM_COMMON_RECORD_HEADER; #define ATOM_I2C_RECORD_TYPE 1 #define ATOM_HPD_INT_RECORD_TYPE 2 #define ATOM_OUTPUT_PROTECTION_RECORD_TYPE 3 #define ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE 4 -#define ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE 5 /* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */ -#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE 6 /* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */ +#define ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE 5 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE +#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE 6 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE #define ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE 7 -#define ATOM_JTAG_RECORD_TYPE 8 /* Obsolete, switch to use GPIO_CNTL_RECORD_TYPE */ +#define ATOM_JTAG_RECORD_TYPE 8 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE #define ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE 9 #define ATOM_ENCODER_DVO_CF_RECORD_TYPE 10 #define ATOM_CONNECTOR_CF_RECORD_TYPE 11 @@ -2667,323 +3307,540 @@ typedef struct _ATOM_COMMON_RECORD_HEADER { #define ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE 13 #define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE 14 #define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE 15 +#define ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE 16 //This is for the case when connectors are not known to object table +#define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE 17 //This is for the case when connectors are not known to object table +#define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record +#define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 -/* Must be updated when new record type is added,equal to that record definition! */ -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_CF_RECORD_TYPE -typedef struct _ATOM_I2C_RECORD { +//Must be updated when new record type is added,equal to that record definition! +#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE + +typedef struct _ATOM_I2C_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; ATOM_I2C_ID_CONFIG sucI2cId; - UCHAR ucI2CAddr; /* The slave address, it's 0 when the record is attached to connector for DDC */ -} ATOM_I2C_RECORD; + UCHAR ucI2CAddr; //The slave address, it's 0 when the record is attached to connector for DDC +}ATOM_I2C_RECORD; -typedef struct _ATOM_HPD_INT_RECORD { +typedef struct _ATOM_HPD_INT_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ + UCHAR ucHPDIntGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info UCHAR ucPlugged_PinState; -} ATOM_HPD_INT_RECORD; +}ATOM_HPD_INT_RECORD; -typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { + +typedef struct _ATOM_OUTPUT_PROTECTION_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucProtectionFlag; UCHAR ucReserved; -} ATOM_OUTPUT_PROTECTION_RECORD; +}ATOM_OUTPUT_PROTECTION_RECORD; -typedef struct _ATOM_CONNECTOR_DEVICE_TAG { - ULONG ulACPIDeviceEnum; /* Reserved for now */ - USHORT usDeviceID; /* This Id is same as "ATOM_DEVICE_XXX_SUPPORT" */ +typedef struct _ATOM_CONNECTOR_DEVICE_TAG +{ + ULONG ulACPIDeviceEnum; //Reserved for now + USHORT usDeviceID; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT" USHORT usPadding; -} ATOM_CONNECTOR_DEVICE_TAG; +}ATOM_CONNECTOR_DEVICE_TAG; -typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD { +typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucNumberOfDevice; UCHAR ucReserved; - ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; /* This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation */ -} ATOM_CONNECTOR_DEVICE_TAG_RECORD; + ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation +}ATOM_CONNECTOR_DEVICE_TAG_RECORD; -typedef struct _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD { + +typedef struct _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucConfigGPIOID; - UCHAR ucConfigGPIOState; /* Set to 1 when it's active high to enable external flow in */ + UCHAR ucConfigGPIOState; //Set to 1 when it's active high to enable external flow in UCHAR ucFlowinGPIPID; UCHAR ucExtInGPIPID; -} ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD; +}ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD; -typedef struct _ATOM_ENCODER_FPGA_CONTROL_RECORD { +typedef struct _ATOM_ENCODER_FPGA_CONTROL_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucCTL1GPIO_ID; - UCHAR ucCTL1GPIOState; /* Set to 1 when it's active high */ + UCHAR ucCTL1GPIOState; //Set to 1 when it's active high UCHAR ucCTL2GPIO_ID; - UCHAR ucCTL2GPIOState; /* Set to 1 when it's active high */ + UCHAR ucCTL2GPIOState; //Set to 1 when it's active high UCHAR ucCTL3GPIO_ID; - UCHAR ucCTL3GPIOState; /* Set to 1 when it's active high */ + UCHAR ucCTL3GPIOState; //Set to 1 when it's active high UCHAR ucCTLFPGA_IN_ID; UCHAR ucPadding[3]; -} ATOM_ENCODER_FPGA_CONTROL_RECORD; +}ATOM_ENCODER_FPGA_CONTROL_RECORD; -typedef struct _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD { +typedef struct _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ - UCHAR ucTVActiveState; /* Indicating when the pin==0 or 1 when TV is connected */ -} ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD; + UCHAR ucGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info + UCHAR ucTVActiveState; //Indicating when the pin==0 or 1 when TV is connected +}ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD; -typedef struct _ATOM_JTAG_RECORD { +typedef struct _ATOM_JTAG_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucTMSGPIO_ID; - UCHAR ucTMSGPIOState; /* Set to 1 when it's active high */ + UCHAR ucTMSGPIOState; //Set to 1 when it's active high UCHAR ucTCKGPIO_ID; - UCHAR ucTCKGPIOState; /* Set to 1 when it's active high */ + UCHAR ucTCKGPIOState; //Set to 1 when it's active high UCHAR ucTDOGPIO_ID; - UCHAR ucTDOGPIOState; /* Set to 1 when it's active high */ + UCHAR ucTDOGPIOState; //Set to 1 when it's active high UCHAR ucTDIGPIO_ID; - UCHAR ucTDIGPIOState; /* Set to 1 when it's active high */ + UCHAR ucTDIGPIOState; //Set to 1 when it's active high UCHAR ucPadding[2]; -} ATOM_JTAG_RECORD; +}ATOM_JTAG_RECORD; -/* The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually */ -typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR { - UCHAR ucGPIOID; /* GPIO_ID, find the corresponding ID in GPIO_LUT table */ - UCHAR ucGPIO_PinState; /* Pin state showing how to set-up the pin */ -} ATOM_GPIO_PIN_CONTROL_PAIR; -typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD { +//The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually +typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR +{ + UCHAR ucGPIOID; // GPIO_ID, find the corresponding ID in GPIO_LUT table + UCHAR ucGPIO_PinState; // Pin state showing how to set-up the pin +}ATOM_GPIO_PIN_CONTROL_PAIR; + +typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucFlags; /* Future expnadibility */ - UCHAR ucNumberOfPins; /* Number of GPIO pins used to control the object */ - ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; /* the real gpio pin pair determined by number of pins ucNumberOfPins */ -} ATOM_OBJECT_GPIO_CNTL_RECORD; + UCHAR ucFlags; // Future expnadibility + UCHAR ucNumberOfPins; // Number of GPIO pins used to control the object + ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; // the real gpio pin pair determined by number of pins ucNumberOfPins +}ATOM_OBJECT_GPIO_CNTL_RECORD; -/* Definitions for GPIO pin state */ +//Definitions for GPIO pin state #define GPIO_PIN_TYPE_INPUT 0x00 #define GPIO_PIN_TYPE_OUTPUT 0x10 #define GPIO_PIN_TYPE_HW_CONTROL 0x20 -/* For GPIO_PIN_TYPE_OUTPUT the following is defined */ +//For GPIO_PIN_TYPE_OUTPUT the following is defined #define GPIO_PIN_OUTPUT_STATE_MASK 0x01 #define GPIO_PIN_OUTPUT_STATE_SHIFT 0 #define GPIO_PIN_STATE_ACTIVE_LOW 0x0 #define GPIO_PIN_STATE_ACTIVE_HIGH 0x1 -typedef struct _ATOM_ENCODER_DVO_CF_RECORD { - ATOM_COMMON_RECORD_HEADER sheader; - ULONG ulStrengthControl; /* DVOA strength control for CF */ - UCHAR ucPadding[2]; -} ATOM_ENCODER_DVO_CF_RECORD; +// Indexes to GPIO array in GLSync record +#define ATOM_GPIO_INDEX_GLSYNC_REFCLK 0 +#define ATOM_GPIO_INDEX_GLSYNC_HSYNC 1 +#define ATOM_GPIO_INDEX_GLSYNC_VSYNC 2 +#define ATOM_GPIO_INDEX_GLSYNC_SWAP_REQ 3 +#define ATOM_GPIO_INDEX_GLSYNC_SWAP_GNT 4 +#define ATOM_GPIO_INDEX_GLSYNC_INTERRUPT 5 +#define ATOM_GPIO_INDEX_GLSYNC_V_RESET 6 +#define ATOM_GPIO_INDEX_GLSYNC_MAX 7 -/* value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle */ +typedef struct _ATOM_ENCODER_DVO_CF_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + ULONG ulStrengthControl; // DVOA strength control for CF + UCHAR ucPadding[2]; +}ATOM_ENCODER_DVO_CF_RECORD; + +// value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 -typedef struct _ATOM_CONNECTOR_CF_RECORD { +typedef struct _ATOM_CONNECTOR_CF_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; USHORT usMaxPixClk; UCHAR ucFlowCntlGpioId; UCHAR ucSwapCntlGpioId; UCHAR ucConnectedDvoBundle; UCHAR ucPadding; -} ATOM_CONNECTOR_CF_RECORD; +}ATOM_CONNECTOR_CF_RECORD; -typedef struct _ATOM_CONNECTOR_HARDCODE_DTD_RECORD { +typedef struct _ATOM_CONNECTOR_HARDCODE_DTD_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; ATOM_DTD_FORMAT asTiming; -} ATOM_CONNECTOR_HARDCODE_DTD_RECORD; +}ATOM_CONNECTOR_HARDCODE_DTD_RECORD; -typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD { - ATOM_COMMON_RECORD_HEADER sheader; /* ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE */ - UCHAR ucSubConnectorType; /* CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A */ +typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; //ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE + UCHAR ucSubConnectorType; //CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A UCHAR ucReserved; -} ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD; +}ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD; -typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD { + +typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucMuxType; /* decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state */ + UCHAR ucMuxType; //decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state UCHAR ucMuxControlPin; - UCHAR ucMuxState[2]; /* for alligment purpose */ -} ATOM_ROUTER_DDC_PATH_SELECT_RECORD; + UCHAR ucMuxState[2]; //for alligment purpose +}ATOM_ROUTER_DDC_PATH_SELECT_RECORD; -typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD { +typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD +{ ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucMuxType; UCHAR ucMuxControlPin; - UCHAR ucMuxState[2]; /* for alligment purpose */ -} ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD; + UCHAR ucMuxState[2]; //for alligment purpose +}ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD; -/* define ucMuxType */ +// define ucMuxType #define ATOM_ROUTER_MUX_PIN_STATE_MASK 0x0f #define ATOM_ROUTER_MUX_PIN_SINGLE_STATE_COMPLEMENT 0x01 +typedef struct _ATOM_CONNECTOR_HPDPIN_LUT_RECORD //record for ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE +{ + ATOM_COMMON_RECORD_HEADER sheader; + UCHAR ucHPDPINMap[MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES]; //An fixed size array which maps external pins to internal GPIO_PIN_INFO table +}ATOM_CONNECTOR_HPDPIN_LUT_RECORD; + +typedef struct _ATOM_CONNECTOR_AUXDDC_LUT_RECORD //record for ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE +{ + ATOM_COMMON_RECORD_HEADER sheader; + ATOM_I2C_ID_CONFIG ucAUXDDCMap[MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES]; //An fixed size array which maps external pins to internal DDC ID +}ATOM_CONNECTOR_AUXDDC_LUT_RECORD; + +typedef struct _ATOM_OBJECT_LINK_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + USHORT usObjectID; //could be connector, encorder or other object in object.h +}ATOM_OBJECT_LINK_RECORD; + +typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + USHORT usReserved; +}ATOM_CONNECTOR_REMOTE_CAP_RECORD; + /****************************************************************************/ -/* ASIC voltage data table */ +// ASIC voltage data table /****************************************************************************/ -typedef struct _ATOM_VOLTAGE_INFO_HEADER { - USHORT usVDDCBaseLevel; /* In number of 50mv unit */ - USHORT usReserved; /* For possible extension table offset */ +typedef struct _ATOM_VOLTAGE_INFO_HEADER +{ + USHORT usVDDCBaseLevel; //In number of 50mv unit + USHORT usReserved; //For possible extension table offset UCHAR ucNumOfVoltageEntries; UCHAR ucBytesPerVoltageEntry; - UCHAR ucVoltageStep; /* Indicating in how many mv increament is one step, 0.5mv unit */ + UCHAR ucVoltageStep; //Indicating in how many mv increament is one step, 0.5mv unit UCHAR ucDefaultVoltageEntry; UCHAR ucVoltageControlI2cLine; UCHAR ucVoltageControlAddress; UCHAR ucVoltageControlOffset; -} ATOM_VOLTAGE_INFO_HEADER; +}ATOM_VOLTAGE_INFO_HEADER; -typedef struct _ATOM_VOLTAGE_INFO { +typedef struct _ATOM_VOLTAGE_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_VOLTAGE_INFO_HEADER viHeader; - UCHAR ucVoltageEntries[64]; /* 64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry */ -} ATOM_VOLTAGE_INFO; + UCHAR ucVoltageEntries[64]; //64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry +}ATOM_VOLTAGE_INFO; -typedef struct _ATOM_VOLTAGE_FORMULA { - USHORT usVoltageBaseLevel; /* In number of 1mv unit */ - USHORT usVoltageStep; /* Indicating in how many mv increament is one step, 1mv unit */ - UCHAR ucNumOfVoltageEntries; /* Number of Voltage Entry, which indicate max Voltage */ - UCHAR ucFlag; /* bit0=0 :step is 1mv =1 0.5mv */ - UCHAR ucBaseVID; /* if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep */ + +typedef struct _ATOM_VOLTAGE_FORMULA +{ + USHORT usVoltageBaseLevel; // In number of 1mv unit + USHORT usVoltageStep; // Indicating in how many mv increament is one step, 1mv unit + UCHAR ucNumOfVoltageEntries; // Number of Voltage Entry, which indicate max Voltage + UCHAR ucFlag; // bit0=0 :step is 1mv =1 0.5mv + UCHAR ucBaseVID; // if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep UCHAR ucReserved; - UCHAR ucVIDAdjustEntries[32]; /* 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries */ -} ATOM_VOLTAGE_FORMULA; + UCHAR ucVIDAdjustEntries[32]; // 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries +}ATOM_VOLTAGE_FORMULA; -typedef struct _ATOM_VOLTAGE_CONTROL { - UCHAR ucVoltageControlId; /* Indicate it is controlled by I2C or GPIO or HW state machine */ +typedef struct _VOLTAGE_LUT_ENTRY +{ + USHORT usVoltageCode; // The Voltage ID, either GPIO or I2C code + USHORT usVoltageValue; // The corresponding Voltage Value, in mV +}VOLTAGE_LUT_ENTRY; + +typedef struct _ATOM_VOLTAGE_FORMULA_V2 +{ + UCHAR ucNumOfVoltageEntries; // Number of Voltage Entry, which indicate max Voltage + UCHAR ucReserved[3]; + VOLTAGE_LUT_ENTRY asVIDAdjustEntries[32];// 32 is for allocation, the actual number of entries is in ucNumOfVoltageEntries +}ATOM_VOLTAGE_FORMULA_V2; + +typedef struct _ATOM_VOLTAGE_CONTROL +{ + UCHAR ucVoltageControlId; //Indicate it is controlled by I2C or GPIO or HW state machine UCHAR ucVoltageControlI2cLine; UCHAR ucVoltageControlAddress; UCHAR ucVoltageControlOffset; - USHORT usGpioPin_AIndex; /* GPIO_PAD register index */ - UCHAR ucGpioPinBitShift[9]; /* at most 8 pin support 255 VIDs, termintate with 0xff */ + USHORT usGpioPin_AIndex; //GPIO_PAD register index + UCHAR ucGpioPinBitShift[9]; //at most 8 pin support 255 VIDs, termintate with 0xff UCHAR ucReserved; -} ATOM_VOLTAGE_CONTROL; +}ATOM_VOLTAGE_CONTROL; -/* Define ucVoltageControlId */ +// Define ucVoltageControlId #define VOLTAGE_CONTROLLED_BY_HW 0x00 #define VOLTAGE_CONTROLLED_BY_I2C_MASK 0x7F #define VOLTAGE_CONTROLLED_BY_GPIO 0x80 -#define VOLTAGE_CONTROL_ID_LM64 0x01 /* I2C control, used for R5xx Core Voltage */ -#define VOLTAGE_CONTROL_ID_DAC 0x02 /* I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI */ -#define VOLTAGE_CONTROL_ID_VT116xM 0x03 /* I2C control, used for R6xx Core Voltage */ +#define VOLTAGE_CONTROL_ID_LM64 0x01 //I2C control, used for R5xx Core Voltage +#define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI +#define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage #define VOLTAGE_CONTROL_ID_DS4402 0x04 -typedef struct _ATOM_VOLTAGE_OBJECT { - UCHAR ucVoltageType; /* Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI */ - UCHAR ucSize; /* Size of Object */ - ATOM_VOLTAGE_CONTROL asControl; /* describ how to control */ - ATOM_VOLTAGE_FORMULA asFormula; /* Indicate How to convert real Voltage to VID */ -} ATOM_VOLTAGE_OBJECT; +typedef struct _ATOM_VOLTAGE_OBJECT +{ + UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI + UCHAR ucSize; //Size of Object + ATOM_VOLTAGE_CONTROL asControl; //describ how to control + ATOM_VOLTAGE_FORMULA asFormula; //Indicate How to convert real Voltage to VID +}ATOM_VOLTAGE_OBJECT; -typedef struct _ATOM_VOLTAGE_OBJECT_INFO { +typedef struct _ATOM_VOLTAGE_OBJECT_V2 +{ + UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI + UCHAR ucSize; //Size of Object + ATOM_VOLTAGE_CONTROL asControl; //describ how to control + ATOM_VOLTAGE_FORMULA_V2 asFormula; //Indicate How to convert real Voltage to VID +}ATOM_VOLTAGE_OBJECT_V2; + +typedef struct _ATOM_VOLTAGE_OBJECT_INFO +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_VOLTAGE_OBJECT asVoltageObj[3]; //Info for Voltage control +}ATOM_VOLTAGE_OBJECT_INFO; + +typedef struct _ATOM_VOLTAGE_OBJECT_INFO_V2 +{ ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VOLTAGE_OBJECT asVoltageObj[3]; /* Info for Voltage control */ -} ATOM_VOLTAGE_OBJECT_INFO; + ATOM_VOLTAGE_OBJECT_V2 asVoltageObj[3]; //Info for Voltage control +}ATOM_VOLTAGE_OBJECT_INFO_V2; -typedef struct _ATOM_LEAKID_VOLTAGE { +typedef struct _ATOM_LEAKID_VOLTAGE +{ UCHAR ucLeakageId; UCHAR ucReserved; USHORT usVoltage; -} ATOM_LEAKID_VOLTAGE; +}ATOM_LEAKID_VOLTAGE; -typedef struct _ATOM_ASIC_PROFILE_VOLTAGE { +typedef struct _ATOM_ASIC_PROFILE_VOLTAGE +{ UCHAR ucProfileId; UCHAR ucReserved; USHORT usSize; USHORT usEfuseSpareStartAddr; - USHORT usFuseIndex[8]; /* from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, */ - ATOM_LEAKID_VOLTAGE asLeakVol[2]; /* Leakid and relatd voltage */ -} ATOM_ASIC_PROFILE_VOLTAGE; + USHORT usFuseIndex[8]; //from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, + ATOM_LEAKID_VOLTAGE asLeakVol[2]; //Leakid and relatd voltage +}ATOM_ASIC_PROFILE_VOLTAGE; -/* ucProfileId */ +//ucProfileId #define ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE 1 #define ATOM_ASIC_PROFILE_ID_EFUSE_PERFORMANCE_VOLTAGE 1 #define ATOM_ASIC_PROFILE_ID_EFUSE_THERMAL_VOLTAGE 2 -typedef struct _ATOM_ASIC_PROFILING_INFO { +typedef struct _ATOM_ASIC_PROFILING_INFO +{ ATOM_COMMON_TABLE_HEADER asHeader; ATOM_ASIC_PROFILE_VOLTAGE asVoltage; -} ATOM_ASIC_PROFILING_INFO; +}ATOM_ASIC_PROFILING_INFO; -typedef struct _ATOM_POWER_SOURCE_OBJECT { - UCHAR ucPwrSrcId; /* Power source */ - UCHAR ucPwrSensorType; /* GPIO, I2C or none */ - UCHAR ucPwrSensId; /* if GPIO detect, it is GPIO id, if I2C detect, it is I2C id */ - UCHAR ucPwrSensSlaveAddr; /* Slave address if I2C detect */ - UCHAR ucPwrSensRegIndex; /* I2C register Index if I2C detect */ - UCHAR ucPwrSensRegBitMask; /* detect which bit is used if I2C detect */ - UCHAR ucPwrSensActiveState; /* high active or low active */ - UCHAR ucReserve[3]; /* reserve */ - USHORT usSensPwr; /* in unit of watt */ -} ATOM_POWER_SOURCE_OBJECT; +typedef struct _ATOM_POWER_SOURCE_OBJECT +{ + UCHAR ucPwrSrcId; // Power source + UCHAR ucPwrSensorType; // GPIO, I2C or none + UCHAR ucPwrSensId; // if GPIO detect, it is GPIO id, if I2C detect, it is I2C id + UCHAR ucPwrSensSlaveAddr; // Slave address if I2C detect + UCHAR ucPwrSensRegIndex; // I2C register Index if I2C detect + UCHAR ucPwrSensRegBitMask; // detect which bit is used if I2C detect + UCHAR ucPwrSensActiveState; // high active or low active + UCHAR ucReserve[3]; // reserve + USHORT usSensPwr; // in unit of watt +}ATOM_POWER_SOURCE_OBJECT; -typedef struct _ATOM_POWER_SOURCE_INFO { +typedef struct _ATOM_POWER_SOURCE_INFO +{ ATOM_COMMON_TABLE_HEADER asHeader; UCHAR asPwrbehave[16]; ATOM_POWER_SOURCE_OBJECT asPwrObj[1]; -} ATOM_POWER_SOURCE_INFO; +}ATOM_POWER_SOURCE_INFO; -/* Define ucPwrSrcId */ + +//Define ucPwrSrcId #define POWERSOURCE_PCIE_ID1 0x00 #define POWERSOURCE_6PIN_CONNECTOR_ID1 0x01 #define POWERSOURCE_8PIN_CONNECTOR_ID1 0x02 #define POWERSOURCE_6PIN_CONNECTOR_ID2 0x04 #define POWERSOURCE_8PIN_CONNECTOR_ID2 0x08 -/* define ucPwrSensorId */ +//define ucPwrSensorId #define POWER_SENSOR_ALWAYS 0x00 #define POWER_SENSOR_GPIO 0x01 #define POWER_SENSOR_I2C 0x02 +typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ULONG ulBootUpEngineClock; + ULONG ulDentistVCOFreq; + ULONG ulBootUpUMAClock; + ULONG ulReserved1[8]; + ULONG ulBootUpReqDisplayVector; + ULONG ulOtherDisplayMisc; + ULONG ulGPUCapInfo; + ULONG ulReserved2[3]; + ULONG ulSystemConfig; + ULONG ulCPUCapInfo; + USHORT usMaxNBVoltage; + USHORT usMinNBVoltage; + USHORT usBootUpNBVoltage; + USHORT usExtDispConnInfoOffset; + UCHAR ucHtcTmpLmt; + UCHAR ucTjOffset; + UCHAR ucMemoryType; + UCHAR ucUMAChannelNumber; + ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10]; + ULONG ulCSR_M3_ARB_CNTL_UVD[10]; + ULONG ulCSR_M3_ARB_CNTL_FS3D[10]; + ULONG ulReserved3[42]; + ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; +}ATOM_INTEGRATED_SYSTEM_INFO_V6; + +/********************************************************************************************************************** +// ATOM_INTEGRATED_SYSTEM_INFO_V6 Description +//ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. +//ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. +//ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. +//ulReserved1[8] Reserved by now, must be 0x0. +//ulBootUpReqDisplayVector VBIOS boot up display IDs +// ATOM_DEVICE_CRT1_SUPPORT 0x0001 +// ATOM_DEVICE_CRT2_SUPPORT 0x0010 +// ATOM_DEVICE_DFP1_SUPPORT 0x0008 +// ATOM_DEVICE_DFP6_SUPPORT 0x0040 +// ATOM_DEVICE_DFP2_SUPPORT 0x0080 +// ATOM_DEVICE_DFP3_SUPPORT 0x0200 +// ATOM_DEVICE_DFP4_SUPPORT 0x0400 +// ATOM_DEVICE_DFP5_SUPPORT 0x0800 +// ATOM_DEVICE_LCD1_SUPPORT 0x0002 +//ulOtherDisplayMisc Other display related flags, not defined yet. +//ulGPUCapInfo TBD +//ulReserved2[3] must be 0x0 for the reserved. +//ulSystemConfig TBD +//ulCPUCapInfo TBD +//usMaxNBVoltage High NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. +//usMinNBVoltage Low NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. +//usBootUpNBVoltage Boot up NB voltage in unit of mv. +//ucHtcTmpLmt Bit [22:16] of D24F3x64 Thermal Control (HTC) Register. +//ucTjOffset Bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed. +//ucMemoryType [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. +//ucUMAChannelNumber System memory channel numbers. +//usExtDispConnectionInfoOffset ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO offset relative to beginning of this table. +//ulCSR_M3_ARB_CNTL_DEFAULT[10] Arrays with values for CSR M3 arbiter for default +//ulCSR_M3_ARB_CNTL_UVD[10] Arrays with values for CSR M3 arbiter for UVD playback. +//ulCSR_M3_ARB_CNTL_FS3D[10] Arrays with values for CSR M3 arbiter for Full Screen 3D applications. +**********************************************************************************************************************/ + /**************************************************************************/ -/* This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design */ -/* Memory SS Info Table */ -/* Define Memory Clock SS chip ID */ +// This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design +//Memory SS Info Table +//Define Memory Clock SS chip ID #define ICS91719 1 #define ICS91720 2 -/* Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol */ -typedef struct _ATOM_I2C_DATA_RECORD { - UCHAR ucNunberOfBytes; /* Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop" */ - UCHAR ucI2CData[1]; /* I2C data in bytes, should be less than 16 bytes usually */ -} ATOM_I2C_DATA_RECORD; +//Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol +typedef struct _ATOM_I2C_DATA_RECORD +{ + UCHAR ucNunberOfBytes; //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop" + UCHAR ucI2CData[1]; //I2C data in bytes, should be less than 16 bytes usually +}ATOM_I2C_DATA_RECORD; -/* Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information */ -typedef struct _ATOM_I2C_DEVICE_SETUP_INFO { - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; /* I2C line and HW/SW assisted cap. */ - UCHAR ucSSChipID; /* SS chip being used */ - UCHAR ucSSChipSlaveAddr; /* Slave Address to set up this SS chip */ - UCHAR ucNumOfI2CDataRecords; /* number of data block */ + +//Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information +typedef struct _ATOM_I2C_DEVICE_SETUP_INFO +{ + ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //I2C line and HW/SW assisted cap. + UCHAR ucSSChipID; //SS chip being used + UCHAR ucSSChipSlaveAddr; //Slave Address to set up this SS chip + UCHAR ucNumOfI2CDataRecords; //number of data block ATOM_I2C_DATA_RECORD asI2CData[1]; -} ATOM_I2C_DEVICE_SETUP_INFO; +}ATOM_I2C_DEVICE_SETUP_INFO; -/* ========================================================================================== */ -typedef struct _ATOM_ASIC_MVDD_INFO { +//========================================================================================== +typedef struct _ATOM_ASIC_MVDD_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1]; -} ATOM_ASIC_MVDD_INFO; +}ATOM_ASIC_MVDD_INFO; -/* ========================================================================================== */ +//========================================================================================== #define ATOM_MCLK_SS_INFO ATOM_ASIC_MVDD_INFO -/* ========================================================================================== */ +//========================================================================================== /**************************************************************************/ -typedef struct _ATOM_ASIC_SS_ASSIGNMENT { - ULONG ulTargetClockRange; /* Clock Out frequence (VCO ), in unit of 10Khz */ - USHORT usSpreadSpectrumPercentage; /* in unit of 0.01% */ - USHORT usSpreadRateInKhz; /* in unit of kHz, modulation freq */ - UCHAR ucClockIndication; /* Indicate which clock source needs SS */ - UCHAR ucSpreadSpectrumMode; /* Bit1=0 Down Spread,=1 Center Spread. */ +typedef struct _ATOM_ASIC_SS_ASSIGNMENT +{ + ULONG ulTargetClockRange; //Clock Out frequence (VCO ), in unit of 10Khz + USHORT usSpreadSpectrumPercentage; //in unit of 0.01% + USHORT usSpreadRateInKhz; //in unit of kHz, modulation freq + UCHAR ucClockIndication; //Indicate which clock source needs SS + UCHAR ucSpreadSpectrumMode; //Bit1=0 Down Spread,=1 Center Spread. UCHAR ucReserved[2]; -} ATOM_ASIC_SS_ASSIGNMENT; +}ATOM_ASIC_SS_ASSIGNMENT; -/* Define ucSpreadSpectrumType */ +//Define ucClockIndication, SW uses the IDs below to search if the SS is requried/enabled on a clock branch/signal type. +//SS is not required or enabled if a match is not found. #define ASIC_INTERNAL_MEMORY_SS 1 #define ASIC_INTERNAL_ENGINE_SS 2 #define ASIC_INTERNAL_UVD_SS 3 +#define ASIC_INTERNAL_SS_ON_TMDS 4 +#define ASIC_INTERNAL_SS_ON_HDMI 5 +#define ASIC_INTERNAL_SS_ON_LVDS 6 +#define ASIC_INTERNAL_SS_ON_DP 7 +#define ASIC_INTERNAL_SS_ON_DCPLL 8 -typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { +typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 +{ + ULONG ulTargetClockRange; //For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz + //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 ) + USHORT usSpreadSpectrumPercentage; //in unit of 0.01% + USHORT usSpreadRateIn10Hz; //in unit of 10Hz, modulation freq + UCHAR ucClockIndication; //Indicate which clock source needs SS + UCHAR ucSpreadSpectrumMode; //Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS + UCHAR ucReserved[2]; +}ATOM_ASIC_SS_ASSIGNMENT_V2; + +//ucSpreadSpectrumMode +//#define ATOM_SS_DOWN_SPREAD_MODE_MASK 0x00000000 +//#define ATOM_SS_DOWN_SPREAD_MODE 0x00000000 +//#define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001 +//#define ATOM_SS_CENTRE_SPREAD_MODE 0x00000001 +//#define ATOM_INTERNAL_SS_MASK 0x00000000 +//#define ATOM_EXTERNAL_SS_MASK 0x00000002 + +typedef struct _ATOM_ASIC_INTERNAL_SS_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_ASIC_SS_ASSIGNMENT asSpreadSpectrum[4]; -} ATOM_ASIC_INTERNAL_SS_INFO; +}ATOM_ASIC_INTERNAL_SS_INFO; -/* ==============================Scratch Pad Definition Portion=============================== */ +typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[1]; //this is point only. +}ATOM_ASIC_INTERNAL_SS_INFO_V2; + +typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3 +{ + ULONG ulTargetClockRange; //For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz + //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 ) + USHORT usSpreadSpectrumPercentage; //in unit of 0.01% + USHORT usSpreadRateIn10Hz; //in unit of 10Hz, modulation freq + UCHAR ucClockIndication; //Indicate which clock source needs SS + UCHAR ucSpreadSpectrumMode; //Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS + UCHAR ucReserved[2]; +}ATOM_ASIC_SS_ASSIGNMENT_V3; + +typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[1]; //this is pointer only. +}ATOM_ASIC_INTERNAL_SS_INFO_V3; + + +//==============================Scratch Pad Definition Portion=============================== #define ATOM_DEVICE_CONNECT_INFO_DEF 0 #define ATOM_ROM_LOCATION_DEF 1 #define ATOM_TV_STANDARD_DEF 2 @@ -2995,7 +3852,8 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_I2C_CHANNEL_STATUS_DEF 8 #define ATOM_I2C_CHANNEL_STATUS1_DEF 9 -/* BIOS_0_SCRATCH Definition */ + +// BIOS_0_SCRATCH Definition #define ATOM_S0_CRT1_MONO 0x00000001L #define ATOM_S0_CRT1_COLOR 0x00000002L #define ATOM_S0_CRT1_MASK (ATOM_S0_CRT1_MONO+ATOM_S0_CRT1_COLOR) @@ -3008,6 +3866,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_CV_DIN_A 0x00000020L #define ATOM_S0_CV_MASK_A (ATOM_S0_CV_A+ATOM_S0_CV_DIN_A) + #define ATOM_S0_CRT2_MONO 0x00000100L #define ATOM_S0_CRT2_COLOR 0x00000200L #define ATOM_S0_CRT2_MASK (ATOM_S0_CRT2_MONO+ATOM_S0_CRT2_COLOR) @@ -3025,16 +3884,15 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_DFP2 0x00020000L #define ATOM_S0_LCD1 0x00040000L #define ATOM_S0_LCD2 0x00080000L -#define ATOM_S0_TV2 0x00100000L +#define ATOM_S0_DFP6 0x00100000L #define ATOM_S0_DFP3 0x00200000L #define ATOM_S0_DFP4 0x00400000L #define ATOM_S0_DFP5 0x00800000L -#define ATOM_S0_DFP_MASK \ - (ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5) +#define ATOM_S0_DFP_MASK ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5 | ATOM_S0_DFP6 -#define ATOM_S0_FAD_REGISTER_BUG 0x02000000L /* If set, indicates we are running a PCIE asic with */ - /* the FAD/HDP reg access bug. Bit is read by DAL */ +#define ATOM_S0_FAD_REGISTER_BUG 0x02000000L // If set, indicates we are running a PCIE asic with + // the FAD/HDP reg access bug. Bit is read by DAL, this is obsolete from RV5xx #define ATOM_S0_THERMAL_STATE_MASK 0x1C000000L #define ATOM_S0_THERMAL_STATE_SHIFT 26 @@ -3046,7 +3904,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 -/* Byte aligned definition for BIOS usage */ +//Byte aligned defintion for BIOS usage #define ATOM_S0_CRT1_MONOb0 0x01 #define ATOM_S0_CRT1_COLORb0 0x02 #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) @@ -3076,8 +3934,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_DFP2b2 0x02 #define ATOM_S0_LCD1b2 0x04 #define ATOM_S0_LCD2b2 0x08 -#define ATOM_S0_TV2b2 0x10 +#define ATOM_S0_DFP6b2 0x10 #define ATOM_S0_DFP3b2 0x20 +#define ATOM_S0_DFP4b2 0x40 +#define ATOM_S0_DFP5b2 0x80 + #define ATOM_S0_THERMAL_STATE_MASKb3 0x1C #define ATOM_S0_THERMAL_STATE_SHIFTb3 2 @@ -3085,43 +3946,20 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S0_SYSTEM_POWER_STATE_MASKb3 0xE0 #define ATOM_S0_LCD1_SHIFT 18 -/* BIOS_1_SCRATCH Definition */ +// BIOS_1_SCRATCH Definition #define ATOM_S1_ROM_LOCATION_MASK 0x0000FFFFL #define ATOM_S1_PCI_BUS_DEV_MASK 0xFFFF0000L -/* BIOS_2_SCRATCH Definition */ +// BIOS_2_SCRATCH Definition #define ATOM_S2_TV1_STANDARD_MASK 0x0000000FL #define ATOM_S2_CURRENT_BL_LEVEL_MASK 0x0000FF00L #define ATOM_S2_CURRENT_BL_LEVEL_SHIFT 8 -#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L -#define ATOM_S2_LCD1_DPMS_STATE 0x00020000L -#define ATOM_S2_TV1_DPMS_STATE 0x00040000L -#define ATOM_S2_DFP1_DPMS_STATE 0x00080000L -#define ATOM_S2_CRT2_DPMS_STATE 0x00100000L -#define ATOM_S2_LCD2_DPMS_STATE 0x00200000L -#define ATOM_S2_TV2_DPMS_STATE 0x00400000L -#define ATOM_S2_DFP2_DPMS_STATE 0x00800000L -#define ATOM_S2_CV_DPMS_STATE 0x01000000L -#define ATOM_S2_DFP3_DPMS_STATE 0x02000000L -#define ATOM_S2_DFP4_DPMS_STATE 0x04000000L -#define ATOM_S2_DFP5_DPMS_STATE 0x08000000L - -#define ATOM_S2_DFP_DPM_STATE \ - (ATOM_S2_DFP1_DPMS_STATE | ATOM_S2_DFP2_DPMS_STATE | \ - ATOM_S2_DFP3_DPMS_STATE | ATOM_S2_DFP4_DPMS_STATE | \ - ATOM_S2_DFP5_DPMS_STATE) - -#define ATOM_S2_DEVICE_DPMS_STATE \ - (ATOM_S2_CRT1_DPMS_STATE + ATOM_S2_LCD1_DPMS_STATE + \ - ATOM_S2_TV1_DPMS_STATE + ATOM_S2_DFP_DPMS_STATE + \ - ATOM_S2_CRT2_DPMS_STATE + ATOM_S2_LCD2_DPMS_STATE + \ - ATOM_S2_TV2_DPMS_STATE + ATOM_S2_CV_DPMS_STATE) - #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK 0x0C000000L #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK_SHIFT 26 #define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGE 0x10000000L +#define ATOM_S2_DEVICE_DPMS_STATE 0x00010000L #define ATOM_S2_VRI_BRIGHT_ENABLE 0x20000000L #define ATOM_S2_DISPLAY_ROTATION_0_DEGREE 0x0 @@ -3131,21 +3969,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L -/* Byte aligned definition for BIOS usage */ + +//Byte aligned defintion for BIOS usage #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF -#define ATOM_S2_CRT1_DPMS_STATEb2 0x01 -#define ATOM_S2_LCD1_DPMS_STATEb2 0x02 -#define ATOM_S2_TV1_DPMS_STATEb2 0x04 -#define ATOM_S2_DFP1_DPMS_STATEb2 0x08 -#define ATOM_S2_CRT2_DPMS_STATEb2 0x10 -#define ATOM_S2_LCD2_DPMS_STATEb2 0x20 -#define ATOM_S2_TV2_DPMS_STATEb2 0x40 -#define ATOM_S2_DFP2_DPMS_STATEb2 0x80 -#define ATOM_S2_CV_DPMS_STATEb3 0x01 -#define ATOM_S2_DFP3_DPMS_STATEb3 0x02 -#define ATOM_S2_DFP4_DPMS_STATEb3 0x04 -#define ATOM_S2_DFP5_DPMS_STATEb3 0x08 +#define ATOM_S2_DEVICE_DPMS_STATEb2 0x01 #define ATOM_S2_DEVICE_DPMS_MASKw1 0x3FF #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3 0x0C @@ -3153,21 +3981,22 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S2_VRI_BRIGHT_ENABLEb3 0x20 #define ATOM_S2_ROTATION_STATE_MASKb3 0xC0 -/* BIOS_3_SCRATCH Definition */ + +// BIOS_3_SCRATCH Definition #define ATOM_S3_CRT1_ACTIVE 0x00000001L #define ATOM_S3_LCD1_ACTIVE 0x00000002L #define ATOM_S3_TV1_ACTIVE 0x00000004L #define ATOM_S3_DFP1_ACTIVE 0x00000008L #define ATOM_S3_CRT2_ACTIVE 0x00000010L #define ATOM_S3_LCD2_ACTIVE 0x00000020L -#define ATOM_S3_TV2_ACTIVE 0x00000040L +#define ATOM_S3_DFP6_ACTIVE 0x00000040L #define ATOM_S3_DFP2_ACTIVE 0x00000080L #define ATOM_S3_CV_ACTIVE 0x00000100L #define ATOM_S3_DFP3_ACTIVE 0x00000200L #define ATOM_S3_DFP4_ACTIVE 0x00000400L #define ATOM_S3_DFP5_ACTIVE 0x00000800L -#define ATOM_S3_DEVICE_ACTIVE_MASK 0x000003FFL +#define ATOM_S3_DEVICE_ACTIVE_MASK 0x00000FFFL #define ATOM_S3_LCD_FULLEXPANSION_ACTIVE 0x00001000L #define ATOM_S3_LCD_EXPANSION_ASPEC_RATIO_ACTIVE 0x00002000L @@ -3178,7 +4007,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_DFP1_CRTC_ACTIVE 0x00080000L #define ATOM_S3_CRT2_CRTC_ACTIVE 0x00100000L #define ATOM_S3_LCD2_CRTC_ACTIVE 0x00200000L -#define ATOM_S3_TV2_CRTC_ACTIVE 0x00400000L +#define ATOM_S3_DFP6_CRTC_ACTIVE 0x00400000L #define ATOM_S3_DFP2_CRTC_ACTIVE 0x00800000L #define ATOM_S3_CV_CRTC_ACTIVE 0x01000000L #define ATOM_S3_DFP3_CRTC_ACTIVE 0x02000000L @@ -3187,17 +4016,18 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_DEVICE_CRTC_ACTIVE_MASK 0x0FFF0000L #define ATOM_S3_ASIC_GUI_ENGINE_HUNG 0x20000000L +//Below two definitions are not supported in pplib, but in the old powerplay in DAL #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L -/* Byte aligned definition for BIOS usage */ +//Byte aligned defintion for BIOS usage #define ATOM_S3_CRT1_ACTIVEb0 0x01 #define ATOM_S3_LCD1_ACTIVEb0 0x02 #define ATOM_S3_TV1_ACTIVEb0 0x04 #define ATOM_S3_DFP1_ACTIVEb0 0x08 #define ATOM_S3_CRT2_ACTIVEb0 0x10 #define ATOM_S3_LCD2_ACTIVEb0 0x20 -#define ATOM_S3_TV2_ACTIVEb0 0x40 +#define ATOM_S3_DFP6_ACTIVEb0 0x40 #define ATOM_S3_DFP2_ACTIVEb0 0x80 #define ATOM_S3_CV_ACTIVEb1 0x01 #define ATOM_S3_DFP3_ACTIVEb1 0x02 @@ -3212,7 +4042,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_DFP1_CRTC_ACTIVEb2 0x08 #define ATOM_S3_CRT2_CRTC_ACTIVEb2 0x10 #define ATOM_S3_LCD2_CRTC_ACTIVEb2 0x20 -#define ATOM_S3_TV2_CRTC_ACTIVEb2 0x40 +#define ATOM_S3_DFP6_CRTC_ACTIVEb2 0x40 #define ATOM_S3_DFP2_CRTC_ACTIVEb2 0x80 #define ATOM_S3_CV_CRTC_ACTIVEb3 0x01 #define ATOM_S3_DFP3_CRTC_ACTIVEb3 0x02 @@ -3221,35 +4051,31 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S3_ACTIVE_CRTC2w1 0xFFF -#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3 0x20 -#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40 -#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3 0x80 - -/* BIOS_4_SCRATCH Definition */ +// BIOS_4_SCRATCH Definition #define ATOM_S4_LCD1_PANEL_ID_MASK 0x000000FFL #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L #define ATOM_S4_LCD1_REFRESH_SHIFT 8 -/* Byte aligned definition for BIOS usage */ +//Byte aligned defintion for BIOS usage #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 -/* BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!! */ +// BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!! #define ATOM_S5_DOS_REQ_CRT1b0 0x01 #define ATOM_S5_DOS_REQ_LCD1b0 0x02 #define ATOM_S5_DOS_REQ_TV1b0 0x04 #define ATOM_S5_DOS_REQ_DFP1b0 0x08 #define ATOM_S5_DOS_REQ_CRT2b0 0x10 #define ATOM_S5_DOS_REQ_LCD2b0 0x20 -#define ATOM_S5_DOS_REQ_TV2b0 0x40 +#define ATOM_S5_DOS_REQ_DFP6b0 0x40 #define ATOM_S5_DOS_REQ_DFP2b0 0x80 #define ATOM_S5_DOS_REQ_CVb1 0x01 #define ATOM_S5_DOS_REQ_DFP3b1 0x02 #define ATOM_S5_DOS_REQ_DFP4b1 0x04 #define ATOM_S5_DOS_REQ_DFP5b1 0x08 -#define ATOM_S5_DOS_REQ_DEVICEw0 0x03FF +#define ATOM_S5_DOS_REQ_DEVICEw0 0x0FFF #define ATOM_S5_DOS_REQ_CRT1 0x0001 #define ATOM_S5_DOS_REQ_LCD1 0x0002 @@ -3257,7 +4083,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S5_DOS_REQ_DFP1 0x0008 #define ATOM_S5_DOS_REQ_CRT2 0x0010 #define ATOM_S5_DOS_REQ_LCD2 0x0020 -#define ATOM_S5_DOS_REQ_TV2 0x0040 +#define ATOM_S5_DOS_REQ_DFP6 0x0040 #define ATOM_S5_DOS_REQ_DFP2 0x0080 #define ATOM_S5_DOS_REQ_CV 0x0100 #define ATOM_S5_DOS_REQ_DFP3 0x0200 @@ -3268,11 +4094,10 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S5_DOS_FORCE_TV1b2 ATOM_S5_DOS_REQ_TV1b0 #define ATOM_S5_DOS_FORCE_CRT2b2 ATOM_S5_DOS_REQ_CRT2b0 #define ATOM_S5_DOS_FORCE_CVb3 ATOM_S5_DOS_REQ_CVb1 -#define ATOM_S5_DOS_FORCE_DEVICEw1 \ - (ATOM_S5_DOS_FORCE_CRT1b2 + ATOM_S5_DOS_FORCE_TV1b2 + \ - ATOM_S5_DOS_FORCE_CRT2b2 + (ATOM_S5_DOS_FORCE_CVb3 << 8)) +#define ATOM_S5_DOS_FORCE_DEVICEw1 (ATOM_S5_DOS_FORCE_CRT1b2+ATOM_S5_DOS_FORCE_TV1b2+ATOM_S5_DOS_FORCE_CRT2b2+\ + (ATOM_S5_DOS_FORCE_CVb3<<8)) -/* BIOS_6_SCRATCH Definition */ +// BIOS_6_SCRATCH Definition #define ATOM_S6_DEVICE_CHANGE 0x00000001L #define ATOM_S6_SCALER_CHANGE 0x00000002L #define ATOM_S6_LID_CHANGE 0x00000004L @@ -3285,11 +4110,11 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_HW_I2C_BUSY_STATE 0x00000200L #define ATOM_S6_THERMAL_STATE_CHANGE 0x00000400L #define ATOM_S6_INTERRUPT_SET_BY_BIOS 0x00000800L -#define ATOM_S6_REQ_LCD_EXPANSION_FULL 0x00001000L /* Normal expansion Request bit for LCD */ -#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO 0x00002000L /* Aspect ratio expansion Request bit for LCD */ +#define ATOM_S6_REQ_LCD_EXPANSION_FULL 0x00001000L //Normal expansion Request bit for LCD +#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO 0x00002000L //Aspect ratio expansion Request bit for LCD -#define ATOM_S6_DISPLAY_STATE_CHANGE 0x00004000L /* This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion */ -#define ATOM_S6_I2C_STATE_CHANGE 0x00008000L /* This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion */ +#define ATOM_S6_DISPLAY_STATE_CHANGE 0x00004000L //This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion +#define ATOM_S6_I2C_STATE_CHANGE 0x00008000L //This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion #define ATOM_S6_ACC_REQ_CRT1 0x00010000L #define ATOM_S6_ACC_REQ_LCD1 0x00020000L @@ -3297,7 +4122,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_ACC_REQ_DFP1 0x00080000L #define ATOM_S6_ACC_REQ_CRT2 0x00100000L #define ATOM_S6_ACC_REQ_LCD2 0x00200000L -#define ATOM_S6_ACC_REQ_TV2 0x00400000L +#define ATOM_S6_ACC_REQ_DFP6 0x00400000L #define ATOM_S6_ACC_REQ_DFP2 0x00800000L #define ATOM_S6_ACC_REQ_CV 0x01000000L #define ATOM_S6_ACC_REQ_DFP3 0x02000000L @@ -3310,7 +4135,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L -/* Byte aligned definition for BIOS usage */ +//Byte aligned defintion for BIOS usage #define ATOM_S6_DEVICE_CHANGEb0 0x01 #define ATOM_S6_SCALER_CHANGEb0 0x02 #define ATOM_S6_LID_CHANGEb0 0x04 @@ -3332,7 +4157,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_ACC_REQ_DFP1b2 0x08 #define ATOM_S6_ACC_REQ_CRT2b2 0x10 #define ATOM_S6_ACC_REQ_LCD2b2 0x20 -#define ATOM_S6_ACC_REQ_TV2b2 0x40 +#define ATOM_S6_ACC_REQ_DFP6b2 0x40 #define ATOM_S6_ACC_REQ_DFP2b2 0x80 #define ATOM_S6_ACC_REQ_CVb3 0x01 #define ATOM_S6_ACC_REQ_DFP3b3 0x02 @@ -3366,7 +4191,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT 30 #define ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT 31 -/* BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!! */ +// BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!! #define ATOM_S7_DOS_MODE_TYPEb0 0x03 #define ATOM_S7_DOS_MODE_VGAb0 0x00 #define ATOM_S7_DOS_MODE_VESAb0 0x01 @@ -3378,14 +4203,14 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8 -/* BIOS_8_SCRATCH Definition */ +// BIOS_8_SCRATCH Definition #define ATOM_S8_I2C_CHANNEL_BUSY_MASK 0x00000FFFF #define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK 0x0FFFF0000 #define ATOM_S8_I2C_CHANNEL_BUSY_SHIFT 0 #define ATOM_S8_I2C_ENGINE_BUSY_SHIFT 16 -/* BIOS_9_SCRATCH Definition */ +// BIOS_9_SCRATCH Definition #ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK #define ATOM_S9_I2C_CHANNEL_COMPLETED_MASK 0x0000FFFF #endif @@ -3399,197 +4224,171 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { #define ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT 16 #endif + #define ATOM_FLAG_SET 0x20 #define ATOM_FLAG_CLEAR 0 -#define CLEAR_ATOM_S6_ACC_MODE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR) -#define SET_ATOM_S6_DEVICE_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_SCALER_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_LID_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S6_ACC_MODE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR) +#define SET_ATOM_S6_DEVICE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_SCALER_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_LID_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_LID_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) |\ - ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_LID_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR) +#define SET_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR) -#define SET_ATOM_S6_DOCK_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8)| \ - ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_DOCK_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_DOCK_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR) +#define SET_ATOM_S6_DOCK_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR) -#define SET_ATOM_S6_THERMAL_STATE_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_THERMAL_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET) +#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_CRITICAL_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_CRITICAL_STATE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR) +#define SET_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR) -#define SET_ATOM_S6_REQ_SCALER \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_REQ_SCALER \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR ) +#define SET_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR ) -#define SET_ATOM_S6_REQ_SCALER_ARATIO \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET ) -#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR ) +#define SET_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET ) +#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR ) -#define SET_ATOM_S6_I2C_STATE_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) +#define SET_ATOM_S6_I2C_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) -#define SET_ATOM_S6_DISPLAY_STATE_CHANGE \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) +#define SET_ATOM_S6_DISPLAY_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) -#define SET_ATOM_S6_DEVICE_RECONFIG \ - ((ATOM_ACC_CHANGE_INFO_DEF << 8) | \ - ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S0_LCD1 \ - ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 ) | \ - ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR ) -#define SET_ATOM_S7_DOS_8BIT_DAC_EN \ - ((ATOM_DOS_MODE_INFO_DEF << 8) | \ - ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET ) -#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN \ - ((ATOM_DOS_MODE_INFO_DEF << 8) | \ - ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR ) +#define SET_ATOM_S6_DEVICE_RECONFIG ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET) +#define CLEAR_ATOM_S0_LCD1 ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 )| ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR ) +#define SET_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET ) +#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR ) /****************************************************************************/ -/* Portion II: Definitinos only used in Driver */ +//Portion II: Definitinos only used in Driver /****************************************************************************/ -/* Macros used by driver */ +// Macros used by driver +#ifdef __cplusplus +#define GetIndexIntoMasterTable(MasterOrData, FieldName) ((reinterpret_cast(&(static_cast(0))->FieldName)-static_cast(0))/sizeof(USHORT)) -#define GetIndexIntoMasterTable(MasterOrData, FieldName) (((char *)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES *)0)->FieldName)-(char *)0)/sizeof(USHORT)) +#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableFormatRevision )&0x3F) +#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableContentRevision)&0x3F) +#else // not __cplusplus +#define GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT)) #define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F) #define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F) +#endif // __cplusplus #define GET_DATA_TABLE_MAJOR_REVISION GET_COMMAND_TABLE_COMMANDSET_REVISION #define GET_DATA_TABLE_MINOR_REVISION GET_COMMAND_TABLE_PARAMETER_REVISION /****************************************************************************/ -/* Portion III: Definitinos only used in VBIOS */ +//Portion III: Definitinos only used in VBIOS /****************************************************************************/ #define ATOM_DAC_SRC 0x80 #define ATOM_SRC_DAC1 0 #define ATOM_SRC_DAC2 0x80 -#ifdef UEFI_BUILD -#define USHORT UTEMP -#endif - -typedef struct _MEMORY_PLLINIT_PARAMETERS { - ULONG ulTargetMemoryClock; /* In 10Khz unit */ - UCHAR ucAction; /* not define yet */ - UCHAR ucFbDiv_Hi; /* Fbdiv Hi byte */ - UCHAR ucFbDiv; /* FB value */ - UCHAR ucPostDiv; /* Post div */ -} MEMORY_PLLINIT_PARAMETERS; +typedef struct _MEMORY_PLLINIT_PARAMETERS +{ + ULONG ulTargetMemoryClock; //In 10Khz unit + UCHAR ucAction; //not define yet + UCHAR ucFbDiv_Hi; //Fbdiv Hi byte + UCHAR ucFbDiv; //FB value + UCHAR ucPostDiv; //Post div +}MEMORY_PLLINIT_PARAMETERS; #define MEMORY_PLLINIT_PS_ALLOCATION MEMORY_PLLINIT_PARAMETERS + #define GPIO_PIN_WRITE 0x01 #define GPIO_PIN_READ 0x00 -typedef struct _GPIO_PIN_CONTROL_PARAMETERS { - UCHAR ucGPIO_ID; /* return value, read from GPIO pins */ - UCHAR ucGPIOBitShift; /* define which bit in uGPIOBitVal need to be update */ - UCHAR ucGPIOBitVal; /* Set/Reset corresponding bit defined in ucGPIOBitMask */ - UCHAR ucAction; /* =GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write */ -} GPIO_PIN_CONTROL_PARAMETERS; +typedef struct _GPIO_PIN_CONTROL_PARAMETERS +{ + UCHAR ucGPIO_ID; //return value, read from GPIO pins + UCHAR ucGPIOBitShift; //define which bit in uGPIOBitVal need to be update + UCHAR ucGPIOBitVal; //Set/Reset corresponding bit defined in ucGPIOBitMask + UCHAR ucAction; //=GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write +}GPIO_PIN_CONTROL_PARAMETERS; -typedef struct _ENABLE_SCALER_PARAMETERS { - UCHAR ucScaler; /* ATOM_SCALER1, ATOM_SCALER2 */ - UCHAR ucEnable; /* ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION */ - UCHAR ucTVStandard; /* */ +typedef struct _ENABLE_SCALER_PARAMETERS +{ + UCHAR ucScaler; // ATOM_SCALER1, ATOM_SCALER2 + UCHAR ucEnable; // ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION + UCHAR ucTVStandard; // UCHAR ucPadding[1]; -} ENABLE_SCALER_PARAMETERS; +}ENABLE_SCALER_PARAMETERS; #define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS -/* ucEnable: */ +//ucEnable: #define SCALER_BYPASS_AUTO_CENTER_NO_REPLICATION 0 #define SCALER_BYPASS_AUTO_CENTER_AUTO_REPLICATION 1 #define SCALER_ENABLE_2TAP_ALPHA_MODE 2 #define SCALER_ENABLE_MULTITAP_MODE 3 -typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS { - ULONG usHWIconHorzVertPosn; /* Hardware Icon Vertical position */ - UCHAR ucHWIconVertOffset; /* Hardware Icon Vertical offset */ - UCHAR ucHWIconHorzOffset; /* Hardware Icon Horizontal offset */ - UCHAR ucSelection; /* ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2 */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ -} ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS; +typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS +{ + ULONG usHWIconHorzVertPosn; // Hardware Icon Vertical position + UCHAR ucHWIconVertOffset; // Hardware Icon Vertical offset + UCHAR ucHWIconHorzOffset; // Hardware Icon Horizontal offset + UCHAR ucSelection; // ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2 + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE +}ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS; -typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION { +typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION +{ ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS sEnableIcon; ENABLE_CRTC_PARAMETERS sReserved; -} ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION; +}ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION; -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS { - USHORT usHight; /* Image Hight */ - USHORT usWidth; /* Image Width */ - UCHAR ucSurface; /* Surface 1 or 2 */ +typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS +{ + USHORT usHight; // Image Hight + USHORT usWidth; // Image Width + UCHAR ucSurface; // Surface 1 or 2 UCHAR ucPadding[3]; -} ENABLE_GRAPH_SURFACE_PARAMETERS; +}ENABLE_GRAPH_SURFACE_PARAMETERS; -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2 { - USHORT usHight; /* Image Hight */ - USHORT usWidth; /* Image Width */ - UCHAR ucSurface; /* Surface 1 or 2 */ - UCHAR ucEnable; /* ATOM_ENABLE or ATOM_DISABLE */ +typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2 +{ + USHORT usHight; // Image Hight + USHORT usWidth; // Image Width + UCHAR ucSurface; // Surface 1 or 2 + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE UCHAR ucPadding[2]; -} ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2; +}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2; -typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION { +typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3 +{ + USHORT usHight; // Image Hight + USHORT usWidth; // Image Width + UCHAR ucSurface; // Surface 1 or 2 + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE + USHORT usDeviceId; // Active Device Id for this surface. If no device, set to 0. +}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3; + +typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION +{ ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface; - ENABLE_YUV_PS_ALLOCATION sReserved; /* Don't set this one */ -} ENABLE_GRAPH_SURFACE_PS_ALLOCATION; + ENABLE_YUV_PS_ALLOCATION sReserved; // Don't set this one +}ENABLE_GRAPH_SURFACE_PS_ALLOCATION; -typedef struct _MEMORY_CLEAN_UP_PARAMETERS { - USHORT usMemoryStart; /* in 8Kb boundry, offset from memory base address */ - USHORT usMemorySize; /* 8Kb blocks aligned */ -} MEMORY_CLEAN_UP_PARAMETERS; +typedef struct _MEMORY_CLEAN_UP_PARAMETERS +{ + USHORT usMemoryStart; //in 8Kb boundry, offset from memory base address + USHORT usMemorySize; //8Kb blocks aligned +}MEMORY_CLEAN_UP_PARAMETERS; #define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS -typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS { - USHORT usX_Size; /* When use as input parameter, usX_Size indicates which CRTC */ +typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS +{ + USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC USHORT usY_Size; -} GET_DISPLAY_SURFACE_SIZE_PARAMETERS; +}GET_DISPLAY_SURFACE_SIZE_PARAMETERS; -typedef struct _INDIRECT_IO_ACCESS { +typedef struct _INDIRECT_IO_ACCESS +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR IOAccessSequence[256]; } INDIRECT_IO_ACCESS; @@ -3615,63 +4414,74 @@ typedef struct _INDIRECT_IO_ACCESS { #define INDIRECT_IO_NBMISC_READ INDIRECT_IO_NBMISC | INDIRECT_READ #define INDIRECT_IO_NBMISC_WRITE INDIRECT_IO_NBMISC | INDIRECT_WRITE -typedef struct _ATOM_OEM_INFO { +typedef struct _ATOM_OEM_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; -} ATOM_OEM_INFO; +}ATOM_OEM_INFO; -typedef struct _ATOM_TV_MODE { - UCHAR ucVMode_Num; /* Video mode number */ - UCHAR ucTV_Mode_Num; /* Internal TV mode number */ -} ATOM_TV_MODE; +typedef struct _ATOM_TV_MODE +{ + UCHAR ucVMode_Num; //Video mode number + UCHAR ucTV_Mode_Num; //Internal TV mode number +}ATOM_TV_MODE; -typedef struct _ATOM_BIOS_INT_TVSTD_MODE { - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usTV_Mode_LUT_Offset; /* Pointer to standard to internal number conversion table */ - USHORT usTV_FIFO_Offset; /* Pointer to FIFO entry table */ - USHORT usNTSC_Tbl_Offset; /* Pointer to SDTV_Mode_NTSC table */ - USHORT usPAL_Tbl_Offset; /* Pointer to SDTV_Mode_PAL table */ - USHORT usCV_Tbl_Offset; /* Pointer to SDTV_Mode_PAL table */ -} ATOM_BIOS_INT_TVSTD_MODE; +typedef struct _ATOM_BIOS_INT_TVSTD_MODE +{ + ATOM_COMMON_TABLE_HEADER sHeader; + USHORT usTV_Mode_LUT_Offset; // Pointer to standard to internal number conversion table + USHORT usTV_FIFO_Offset; // Pointer to FIFO entry table + USHORT usNTSC_Tbl_Offset; // Pointer to SDTV_Mode_NTSC table + USHORT usPAL_Tbl_Offset; // Pointer to SDTV_Mode_PAL table + USHORT usCV_Tbl_Offset; // Pointer to SDTV_Mode_PAL table +}ATOM_BIOS_INT_TVSTD_MODE; -typedef struct _ATOM_TV_MODE_SCALER_PTR { - USHORT ucFilter0_Offset; /* Pointer to filter format 0 coefficients */ - USHORT usFilter1_Offset; /* Pointer to filter format 0 coefficients */ + +typedef struct _ATOM_TV_MODE_SCALER_PTR +{ + USHORT ucFilter0_Offset; //Pointer to filter format 0 coefficients + USHORT usFilter1_Offset; //Pointer to filter format 0 coefficients UCHAR ucTV_Mode_Num; -} ATOM_TV_MODE_SCALER_PTR; +}ATOM_TV_MODE_SCALER_PTR; -typedef struct _ATOM_STANDARD_VESA_TIMING { +typedef struct _ATOM_STANDARD_VESA_TIMING +{ ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_DTD_FORMAT aModeTimings[16]; /* 16 is not the real array number, just for initial allocation */ -} ATOM_STANDARD_VESA_TIMING; + ATOM_DTD_FORMAT aModeTimings[16]; // 16 is not the real array number, just for initial allocation +}ATOM_STANDARD_VESA_TIMING; -typedef struct _ATOM_STD_FORMAT { + +typedef struct _ATOM_STD_FORMAT +{ USHORT usSTD_HDisp; USHORT usSTD_VDisp; USHORT usSTD_RefreshRate; USHORT usReserved; -} ATOM_STD_FORMAT; +}ATOM_STD_FORMAT; -typedef struct _ATOM_VESA_TO_EXTENDED_MODE { +typedef struct _ATOM_VESA_TO_EXTENDED_MODE +{ USHORT usVESA_ModeNumber; USHORT usExtendedModeNumber; -} ATOM_VESA_TO_EXTENDED_MODE; +}ATOM_VESA_TO_EXTENDED_MODE; -typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT { +typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT +{ ATOM_COMMON_TABLE_HEADER sHeader; ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76]; -} ATOM_VESA_TO_INTENAL_MODE_LUT; +}ATOM_VESA_TO_INTENAL_MODE_LUT; /*************** ATOM Memory Related Data Structure ***********************/ -typedef struct _ATOM_MEMORY_VENDOR_BLOCK { +typedef struct _ATOM_MEMORY_VENDOR_BLOCK{ UCHAR ucMemoryType; UCHAR ucMemoryVendor; UCHAR ucAdjMCId; UCHAR ucDynClkId; ULONG ulDllResetClkRange; -} ATOM_MEMORY_VENDOR_BLOCK; +}ATOM_MEMORY_VENDOR_BLOCK; -typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG { + +typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG{ #if ATOM_BIG_ENDIAN ULONG ucMemBlkId:8; ULONG ulMemClockRange:24; @@ -3679,29 +4489,33 @@ typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG { ULONG ulMemClockRange:24; ULONG ucMemBlkId:8; #endif -} ATOM_MEMORY_SETTING_ID_CONFIG; +}ATOM_MEMORY_SETTING_ID_CONFIG; -typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS { +typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS +{ ATOM_MEMORY_SETTING_ID_CONFIG slAccess; ULONG ulAccess; -} ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS; +}ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS; -typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK { + +typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{ ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID; ULONG aulMemData[1]; -} ATOM_MEMORY_SETTING_DATA_BLOCK; +}ATOM_MEMORY_SETTING_DATA_BLOCK; -typedef struct _ATOM_INIT_REG_INDEX_FORMAT { - USHORT usRegIndex; /* MC register index */ - UCHAR ucPreRegDataLength; /* offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf */ -} ATOM_INIT_REG_INDEX_FORMAT; -typedef struct _ATOM_INIT_REG_BLOCK { - USHORT usRegIndexTblSize; /* size of asRegIndexBuf */ - USHORT usRegDataBlkSize; /* size of ATOM_MEMORY_SETTING_DATA_BLOCK */ +typedef struct _ATOM_INIT_REG_INDEX_FORMAT{ + USHORT usRegIndex; // MC register index + UCHAR ucPreRegDataLength; // offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf +}ATOM_INIT_REG_INDEX_FORMAT; + + +typedef struct _ATOM_INIT_REG_BLOCK{ + USHORT usRegIndexTblSize; //size of asRegIndexBuf + USHORT usRegDataBlkSize; //size of ATOM_MEMORY_SETTING_DATA_BLOCK ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[1]; ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[1]; -} ATOM_INIT_REG_BLOCK; +}ATOM_INIT_REG_BLOCK; #define END_OF_REG_INDEX_BLOCK 0x0ffff #define END_OF_REG_DATA_BLOCK 0x00000000 @@ -3716,7 +4530,9 @@ typedef struct _ATOM_INIT_REG_BLOCK { #define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) #define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) -typedef struct _ATOM_MC_INIT_PARAM_TABLE { + +typedef struct _ATOM_MC_INIT_PARAM_TABLE +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usAdjustARB_SEQDataOffset; USHORT usMCInitMemTypeTblOffset; @@ -3725,7 +4541,8 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE { ULONG ulARB_SEQDataBuf[32]; ATOM_INIT_REG_BLOCK asMCInitMemType; ATOM_INIT_REG_BLOCK asMCInitCommon; -} ATOM_MC_INIT_PARAM_TABLE; +}ATOM_MC_INIT_PARAM_TABLE; + #define _4Mx16 0x2 #define _4Mx32 0x3 @@ -3751,15 +4568,17 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE { #define QIMONDA INFINEON #define PROMOS MOSEL +#define KRETON INFINEON -/* ///////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// */ +/////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// #define UCODE_ROM_START_ADDRESS 0x1c000 -#define UCODE_SIGNATURE 0x4375434d /* 'MCuC' - MC uCode */ +#define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode -/* uCode block header for reference */ +//uCode block header for reference -typedef struct _MCuCodeHeader { +typedef struct _MCuCodeHeader +{ ULONG ulSignature; UCHAR ucRevision; UCHAR ucChecksum; @@ -3771,201 +4590,250 @@ typedef struct _MCuCodeHeader { USHORT usReserved2; } MCuCodeHeader; -/* //////////////////////////////////////////////////////////////////////////////// */ +////////////////////////////////////////////////////////////////////////////////// #define ATOM_MAX_NUMBER_OF_VRAM_MODULE 16 #define ATOM_VRAM_MODULE_MEMORY_VENDOR_ID_MASK 0xF -typedef struct _ATOM_VRAM_MODULE_V1 { +typedef struct _ATOM_VRAM_MODULE_V1 +{ ULONG ulReserved; USHORT usEMRSValue; USHORT usMRSValue; USHORT usReserved; - UCHAR ucExtMemoryID; /* An external indicator (by hardcode, callback or pin) to tell what is the current memory module */ - UCHAR ucMemoryType; /* [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved; */ - UCHAR ucMemoryVenderID; /* Predefined,never change across designs or memory type/vender */ - UCHAR ucMemoryDeviceCfg; /* [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... */ - UCHAR ucRow; /* Number of Row,in power of 2; */ - UCHAR ucColumn; /* Number of Column,in power of 2; */ - UCHAR ucBank; /* Nunber of Bank; */ - UCHAR ucRank; /* Number of Rank, in power of 2 */ - UCHAR ucChannelNum; /* Number of channel; */ - UCHAR ucChannelConfig; /* [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 */ - UCHAR ucDefaultMVDDQ_ID; /* Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; */ - UCHAR ucDefaultMVDDC_ID; /* Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; */ + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved; + UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender + UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... + UCHAR ucRow; // Number of Row,in power of 2; + UCHAR ucColumn; // Number of Column,in power of 2; + UCHAR ucBank; // Nunber of Bank; + UCHAR ucRank; // Number of Rank, in power of 2 + UCHAR ucChannelNum; // Number of channel; + UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 + UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; + UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; UCHAR ucReserved[2]; -} ATOM_VRAM_MODULE_V1; +}ATOM_VRAM_MODULE_V1; -typedef struct _ATOM_VRAM_MODULE_V2 { + +typedef struct _ATOM_VRAM_MODULE_V2 +{ ULONG ulReserved; - ULONG ulFlags; /* To enable/disable functionalities based on memory type */ - ULONG ulEngineClock; /* Override of default engine clock for particular memory type */ - ULONG ulMemoryClock; /* Override of default memory clock for particular memory type */ - USHORT usEMRS2Value; /* EMRS2 Value is used for GDDR2 and GDDR4 memory type */ - USHORT usEMRS3Value; /* EMRS3 Value is used for GDDR2 and GDDR4 memory type */ + ULONG ulFlags; // To enable/disable functionalities based on memory type + ULONG ulEngineClock; // Override of default engine clock for particular memory type + ULONG ulMemoryClock; // Override of default memory clock for particular memory type + USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type + USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type USHORT usEMRSValue; USHORT usMRSValue; USHORT usReserved; - UCHAR ucExtMemoryID; /* An external indicator (by hardcode, callback or pin) to tell what is the current memory module */ - UCHAR ucMemoryType; /* [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; */ - UCHAR ucMemoryVenderID; /* Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed */ - UCHAR ucMemoryDeviceCfg; /* [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... */ - UCHAR ucRow; /* Number of Row,in power of 2; */ - UCHAR ucColumn; /* Number of Column,in power of 2; */ - UCHAR ucBank; /* Nunber of Bank; */ - UCHAR ucRank; /* Number of Rank, in power of 2 */ - UCHAR ucChannelNum; /* Number of channel; */ - UCHAR ucChannelConfig; /* [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 */ - UCHAR ucDefaultMVDDQ_ID; /* Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; */ - UCHAR ucDefaultMVDDC_ID; /* Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; */ + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; + UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed + UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... + UCHAR ucRow; // Number of Row,in power of 2; + UCHAR ucColumn; // Number of Column,in power of 2; + UCHAR ucBank; // Nunber of Bank; + UCHAR ucRank; // Number of Rank, in power of 2 + UCHAR ucChannelNum; // Number of channel; + UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 + UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; + UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; UCHAR ucRefreshRateFactor; UCHAR ucReserved[3]; -} ATOM_VRAM_MODULE_V2; +}ATOM_VRAM_MODULE_V2; -typedef struct _ATOM_MEMORY_TIMING_FORMAT { - ULONG ulClkRange; /* memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing */ - union { - USHORT usMRS; /* mode register */ + +typedef struct _ATOM_MEMORY_TIMING_FORMAT +{ + ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing + union{ + USHORT usMRS; // mode register USHORT usDDR3_MR0; }; - union { - USHORT usEMRS; /* extended mode register */ + union{ + USHORT usEMRS; // extended mode register USHORT usDDR3_MR1; }; - UCHAR ucCL; /* CAS latency */ - UCHAR ucWL; /* WRITE Latency */ - UCHAR uctRAS; /* tRAS */ - UCHAR uctRC; /* tRC */ - UCHAR uctRFC; /* tRFC */ - UCHAR uctRCDR; /* tRCDR */ - UCHAR uctRCDW; /* tRCDW */ - UCHAR uctRP; /* tRP */ - UCHAR uctRRD; /* tRRD */ - UCHAR uctWR; /* tWR */ - UCHAR uctWTR; /* tWTR */ - UCHAR uctPDIX; /* tPDIX */ - UCHAR uctFAW; /* tFAW */ - UCHAR uctAOND; /* tAOND */ - union { + UCHAR ucCL; // CAS latency + UCHAR ucWL; // WRITE Latency + UCHAR uctRAS; // tRAS + UCHAR uctRC; // tRC + UCHAR uctRFC; // tRFC + UCHAR uctRCDR; // tRCDR + UCHAR uctRCDW; // tRCDW + UCHAR uctRP; // tRP + UCHAR uctRRD; // tRRD + UCHAR uctWR; // tWR + UCHAR uctWTR; // tWTR + UCHAR uctPDIX; // tPDIX + UCHAR uctFAW; // tFAW + UCHAR uctAOND; // tAOND + union + { struct { - UCHAR ucflag; /* flag to control memory timing calculation. bit0= control EMRS2 Infineon */ + UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon UCHAR ucReserved; }; USHORT usDDR3_MR2; }; -} ATOM_MEMORY_TIMING_FORMAT; +}ATOM_MEMORY_TIMING_FORMAT; -typedef struct _ATOM_MEMORY_TIMING_FORMAT_V1 { - ULONG ulClkRange; /* memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing */ - USHORT usMRS; /* mode register */ - USHORT usEMRS; /* extended mode register */ - UCHAR ucCL; /* CAS latency */ - UCHAR ucWL; /* WRITE Latency */ - UCHAR uctRAS; /* tRAS */ - UCHAR uctRC; /* tRC */ - UCHAR uctRFC; /* tRFC */ - UCHAR uctRCDR; /* tRCDR */ - UCHAR uctRCDW; /* tRCDW */ - UCHAR uctRP; /* tRP */ - UCHAR uctRRD; /* tRRD */ - UCHAR uctWR; /* tWR */ - UCHAR uctWTR; /* tWTR */ - UCHAR uctPDIX; /* tPDIX */ - UCHAR uctFAW; /* tFAW */ - UCHAR uctAOND; /* tAOND */ - UCHAR ucflag; /* flag to control memory timing calculation. bit0= control EMRS2 Infineon */ -/* ///////////////////////GDDR parameters/////////////////////////////////// */ - UCHAR uctCCDL; /* */ - UCHAR uctCRCRL; /* */ - UCHAR uctCRCWL; /* */ - UCHAR uctCKE; /* */ - UCHAR uctCKRSE; /* */ - UCHAR uctCKRSX; /* */ - UCHAR uctFAW32; /* */ - UCHAR ucReserved1; /* */ - UCHAR ucReserved2; /* */ + +typedef struct _ATOM_MEMORY_TIMING_FORMAT_V1 +{ + ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing + USHORT usMRS; // mode register + USHORT usEMRS; // extended mode register + UCHAR ucCL; // CAS latency + UCHAR ucWL; // WRITE Latency + UCHAR uctRAS; // tRAS + UCHAR uctRC; // tRC + UCHAR uctRFC; // tRFC + UCHAR uctRCDR; // tRCDR + UCHAR uctRCDW; // tRCDW + UCHAR uctRP; // tRP + UCHAR uctRRD; // tRRD + UCHAR uctWR; // tWR + UCHAR uctWTR; // tWTR + UCHAR uctPDIX; // tPDIX + UCHAR uctFAW; // tFAW + UCHAR uctAOND; // tAOND + UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon +////////////////////////////////////GDDR parameters/////////////////////////////////// + UCHAR uctCCDL; // + UCHAR uctCRCRL; // + UCHAR uctCRCWL; // + UCHAR uctCKE; // + UCHAR uctCKRSE; // + UCHAR uctCKRSX; // + UCHAR uctFAW32; // + UCHAR ucMR5lo; // + UCHAR ucMR5hi; // + UCHAR ucTerminator; +}ATOM_MEMORY_TIMING_FORMAT_V1; + +typedef struct _ATOM_MEMORY_TIMING_FORMAT_V2 +{ + ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing + USHORT usMRS; // mode register + USHORT usEMRS; // extended mode register + UCHAR ucCL; // CAS latency + UCHAR ucWL; // WRITE Latency + UCHAR uctRAS; // tRAS + UCHAR uctRC; // tRC + UCHAR uctRFC; // tRFC + UCHAR uctRCDR; // tRCDR + UCHAR uctRCDW; // tRCDW + UCHAR uctRP; // tRP + UCHAR uctRRD; // tRRD + UCHAR uctWR; // tWR + UCHAR uctWTR; // tWTR + UCHAR uctPDIX; // tPDIX + UCHAR uctFAW; // tFAW + UCHAR uctAOND; // tAOND + UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon +////////////////////////////////////GDDR parameters/////////////////////////////////// + UCHAR uctCCDL; // + UCHAR uctCRCRL; // + UCHAR uctCRCWL; // + UCHAR uctCKE; // + UCHAR uctCKRSE; // + UCHAR uctCKRSX; // + UCHAR uctFAW32; // + UCHAR ucMR4lo; // + UCHAR ucMR4hi; // + UCHAR ucMR5lo; // + UCHAR ucMR5hi; // UCHAR ucTerminator; -} ATOM_MEMORY_TIMING_FORMAT_V1; + UCHAR ucReserved; +}ATOM_MEMORY_TIMING_FORMAT_V2; -typedef struct _ATOM_MEMORY_FORMAT { - ULONG ulDllDisClock; /* memory DLL will be disable when target memory clock is below this clock */ - union { - USHORT usEMRS2Value; /* EMRS2 Value is used for GDDR2 and GDDR4 memory type */ - USHORT usDDR3_Reserved; /* Not used for DDR3 memory */ +typedef struct _ATOM_MEMORY_FORMAT +{ + ULONG ulDllDisClock; // memory DLL will be disable when target memory clock is below this clock + union{ + USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type + USHORT usDDR3_Reserved; // Not used for DDR3 memory }; - union { - USHORT usEMRS3Value; /* EMRS3 Value is used for GDDR2 and GDDR4 memory type */ - USHORT usDDR3_MR3; /* Used for DDR3 memory */ + union{ + USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type + USHORT usDDR3_MR3; // Used for DDR3 memory }; - UCHAR ucMemoryType; /* [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; */ - UCHAR ucMemoryVenderID; /* Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed */ - UCHAR ucRow; /* Number of Row,in power of 2; */ - UCHAR ucColumn; /* Number of Column,in power of 2; */ - UCHAR ucBank; /* Nunber of Bank; */ - UCHAR ucRank; /* Number of Rank, in power of 2 */ - UCHAR ucBurstSize; /* burst size, 0= burst size=4 1= burst size=8 */ - UCHAR ucDllDisBit; /* position of DLL Enable/Disable bit in EMRS ( Extended Mode Register ) */ - UCHAR ucRefreshRateFactor; /* memory refresh rate in unit of ms */ - UCHAR ucDensity; /* _8Mx32, _16Mx32, _16Mx16, _32Mx16 */ - UCHAR ucPreamble; /* [7:4] Write Preamble, [3:0] Read Preamble */ - UCHAR ucMemAttrib; /* Memory Device Addribute, like RDBI/WDBI etc */ - ATOM_MEMORY_TIMING_FORMAT asMemTiming[5]; /* Memory Timing block sort from lower clock to higher clock */ -} ATOM_MEMORY_FORMAT; + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; + UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed + UCHAR ucRow; // Number of Row,in power of 2; + UCHAR ucColumn; // Number of Column,in power of 2; + UCHAR ucBank; // Nunber of Bank; + UCHAR ucRank; // Number of Rank, in power of 2 + UCHAR ucBurstSize; // burst size, 0= burst size=4 1= burst size=8 + UCHAR ucDllDisBit; // position of DLL Enable/Disable bit in EMRS ( Extended Mode Register ) + UCHAR ucRefreshRateFactor; // memory refresh rate in unit of ms + UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 + UCHAR ucPreamble; //[7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemAttrib; // Memory Device Addribute, like RDBI/WDBI etc + ATOM_MEMORY_TIMING_FORMAT asMemTiming[5]; //Memory Timing block sort from lower clock to higher clock +}ATOM_MEMORY_FORMAT; -typedef struct _ATOM_VRAM_MODULE_V3 { - ULONG ulChannelMapCfg; /* board dependent paramenter:Channel combination */ - USHORT usSize; /* size of ATOM_VRAM_MODULE_V3 */ - USHORT usDefaultMVDDQ; /* board dependent parameter:Default Memory Core Voltage */ - USHORT usDefaultMVDDC; /* board dependent parameter:Default Memory IO Voltage */ - UCHAR ucExtMemoryID; /* An external indicator (by hardcode, callback or pin) to tell what is the current memory module */ - UCHAR ucChannelNum; /* board dependent parameter:Number of channel; */ - UCHAR ucChannelSize; /* board dependent parameter:32bit or 64bit */ - UCHAR ucVREFI; /* board dependnt parameter: EXT or INT +160mv to -140mv */ - UCHAR ucNPL_RT; /* board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */ - UCHAR ucFlag; /* To enable/disable functionalities based on memory type */ - ATOM_MEMORY_FORMAT asMemory; /* describ all of video memory parameters from memory spec */ -} ATOM_VRAM_MODULE_V3; -/* ATOM_VRAM_MODULE_V3.ucNPL_RT */ +typedef struct _ATOM_VRAM_MODULE_V3 +{ + ULONG ulChannelMapCfg; // board dependent paramenter:Channel combination + USHORT usSize; // size of ATOM_VRAM_MODULE_V3 + USHORT usDefaultMVDDQ; // board dependent parameter:Default Memory Core Voltage + USHORT usDefaultMVDDC; // board dependent parameter:Default Memory IO Voltage + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucChannelNum; // board dependent parameter:Number of channel; + UCHAR ucChannelSize; // board dependent parameter:32bit or 64bit + UCHAR ucVREFI; // board dependnt parameter: EXT or INT +160mv to -140mv + UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters + UCHAR ucFlag; // To enable/disable functionalities based on memory type + ATOM_MEMORY_FORMAT asMemory; // describ all of video memory parameters from memory spec +}ATOM_VRAM_MODULE_V3; + + +//ATOM_VRAM_MODULE_V3.ucNPL_RT #define NPL_RT_MASK 0x0f #define BATTERY_ODT_MASK 0xc0 #define ATOM_VRAM_MODULE ATOM_VRAM_MODULE_V3 -typedef struct _ATOM_VRAM_MODULE_V4 { - ULONG ulChannelMapCfg; /* board dependent parameter: Channel combination */ - USHORT usModuleSize; /* size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE */ - USHORT usPrivateReserved; /* BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */ - /* MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) */ +typedef struct _ATOM_VRAM_MODULE_V4 +{ + ULONG ulChannelMapCfg; // board dependent parameter: Channel combination + USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE + USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) USHORT usReserved; - UCHAR ucExtMemoryID; /* An external indicator (by hardcode, callback or pin) to tell what is the current memory module */ - UCHAR ucMemoryType; /* [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; */ - UCHAR ucChannelNum; /* Number of channels present in this module config */ - UCHAR ucChannelWidth; /* 0 - 32 bits; 1 - 64 bits */ - UCHAR ucDensity; /* _8Mx32, _16Mx32, _16Mx16, _32Mx16 */ - UCHAR ucFlag; /* To enable/disable functionalities based on memory type */ - UCHAR ucMisc; /* bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 */ - UCHAR ucVREFI; /* board dependent parameter */ - UCHAR ucNPL_RT; /* board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */ - UCHAR ucPreamble; /* [7:4] Write Preamble, [3:0] Read Preamble */ - UCHAR ucMemorySize; /* BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */ - /* Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros */ + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; + UCHAR ucChannelNum; // Number of channels present in this module config + UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits + UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 + UCHAR ucFlag; // To enable/disable functionalities based on memory type + UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 + UCHAR ucVREFI; // board dependent parameter + UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters + UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros UCHAR ucReserved[3]; -/* compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level */ - union { - USHORT usEMRS2Value; /* EMRS2 Value is used for GDDR2 and GDDR4 memory type */ +//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level + union{ + USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type USHORT usDDR3_Reserved; }; - union { - USHORT usEMRS3Value; /* EMRS3 Value is used for GDDR2 and GDDR4 memory type */ - USHORT usDDR3_MR3; /* Used for DDR3 memory */ + union{ + USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type + USHORT usDDR3_MR3; // Used for DDR3 memory }; - UCHAR ucMemoryVenderID; /* Predefined, If not predefined, vendor detection table gets executed */ - UCHAR ucRefreshRateFactor; /* [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) */ + UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed + UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) UCHAR ucReserved2[2]; - ATOM_MEMORY_TIMING_FORMAT asMemTiming[5]; /* Memory Timing block sort from lower clock to higher clock */ -} ATOM_VRAM_MODULE_V4; + ATOM_MEMORY_TIMING_FORMAT asMemTiming[5];//Memory Timing block sort from lower clock to higher clock +}ATOM_VRAM_MODULE_V4; #define VRAM_MODULE_V4_MISC_RANK_MASK 0x3 #define VRAM_MODULE_V4_MISC_DUAL_RANK 0x1 @@ -3973,83 +4841,125 @@ typedef struct _ATOM_VRAM_MODULE_V4 { #define VRAM_MODULE_V4_MISC_BL8 0x4 #define VRAM_MODULE_V4_MISC_DUAL_CS 0x10 -typedef struct _ATOM_VRAM_MODULE_V5 { - ULONG ulChannelMapCfg; /* board dependent parameter: Channel combination */ - USHORT usModuleSize; /* size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE */ - USHORT usPrivateReserved; /* BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */ - /* MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) */ +typedef struct _ATOM_VRAM_MODULE_V5 +{ + ULONG ulChannelMapCfg; // board dependent parameter: Channel combination + USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE + USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) + USHORT usReserved; + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; + UCHAR ucChannelNum; // Number of channels present in this module config + UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits + UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 + UCHAR ucFlag; // To enable/disable functionalities based on memory type + UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 + UCHAR ucVREFI; // board dependent parameter + UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters + UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros + UCHAR ucReserved[3]; + +//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level + USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type + USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type + UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed + UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) + UCHAR ucFIFODepth; // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth + UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth + ATOM_MEMORY_TIMING_FORMAT_V1 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock +}ATOM_VRAM_MODULE_V5; + +typedef struct _ATOM_VRAM_MODULE_V6 +{ + ULONG ulChannelMapCfg; // board dependent parameter: Channel combination + USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE + USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) USHORT usReserved; - UCHAR ucExtMemoryID; /* An external indicator (by hardcode, callback or pin) to tell what is the current memory module */ - UCHAR ucMemoryType; /* [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; */ - UCHAR ucChannelNum; /* Number of channels present in this module config */ - UCHAR ucChannelWidth; /* 0 - 32 bits; 1 - 64 bits */ - UCHAR ucDensity; /* _8Mx32, _16Mx32, _16Mx16, _32Mx16 */ - UCHAR ucFlag; /* To enable/disable functionalities based on memory type */ - UCHAR ucMisc; /* bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 */ - UCHAR ucVREFI; /* board dependent parameter */ - UCHAR ucNPL_RT; /* board dependent parameter:NPL round trip delay, used for calculate memory timing parameters */ - UCHAR ucPreamble; /* [7:4] Write Preamble, [3:0] Read Preamble */ - UCHAR ucMemorySize; /* BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! */ - /* Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros */ + UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module + UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; + UCHAR ucChannelNum; // Number of channels present in this module config + UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits + UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 + UCHAR ucFlag; // To enable/disable functionalities based on memory type + UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 + UCHAR ucVREFI; // board dependent parameter + UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters + UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! + // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros UCHAR ucReserved[3]; -/* compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level */ - USHORT usEMRS2Value; /* EMRS2 Value is used for GDDR2 and GDDR4 memory type */ - USHORT usEMRS3Value; /* EMRS3 Value is used for GDDR2 and GDDR4 memory type */ - UCHAR ucMemoryVenderID; /* Predefined, If not predefined, vendor detection table gets executed */ - UCHAR ucRefreshRateFactor; /* [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) */ - UCHAR ucFIFODepth; /* FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth */ - UCHAR ucCDR_Bandwidth; /* [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth */ - ATOM_MEMORY_TIMING_FORMAT_V1 asMemTiming[5]; /* Memory Timing block sort from lower clock to higher clock */ -} ATOM_VRAM_MODULE_V5; +//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level + USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type + USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type + UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed + UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) + UCHAR ucFIFODepth; // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth + UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth + ATOM_MEMORY_TIMING_FORMAT_V2 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock +}ATOM_VRAM_MODULE_V6; -typedef struct _ATOM_VRAM_INFO_V2 { + + +typedef struct _ATOM_VRAM_INFO_V2 +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; /* just for allocation, real number of blocks is in ucNumOfVRAMModule; */ -} ATOM_VRAM_INFO_V2; + ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; +}ATOM_VRAM_INFO_V2; -typedef struct _ATOM_VRAM_INFO_V3 { +typedef struct _ATOM_VRAM_INFO_V3 +{ ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMemAdjustTblOffset; /* offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting */ - USHORT usMemClkPatchTblOffset; /* offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting */ + USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting + USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting USHORT usRerseved; - UCHAR aVID_PinsShift[9]; /* 8 bit strap maximum+terminator */ + UCHAR aVID_PinsShift[9]; // 8 bit strap maximum+terminator UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; /* just for allocation, real number of blocks is in ucNumOfVRAMModule; */ - ATOM_INIT_REG_BLOCK asMemPatch; /* for allocation */ - /* ATOM_INIT_REG_BLOCK aMemAdjust; */ -} ATOM_VRAM_INFO_V3; + ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; + ATOM_INIT_REG_BLOCK asMemPatch; // for allocation + // ATOM_INIT_REG_BLOCK aMemAdjust; +}ATOM_VRAM_INFO_V3; #define ATOM_VRAM_INFO_LAST ATOM_VRAM_INFO_V3 -typedef struct _ATOM_VRAM_INFO_V4 { +typedef struct _ATOM_VRAM_INFO_V4 +{ ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMemAdjustTblOffset; /* offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting */ - USHORT usMemClkPatchTblOffset; /* offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting */ + USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting + USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting USHORT usRerseved; - UCHAR ucMemDQ7_0ByteRemap; /* DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 */ - ULONG ulMemDQ7_0BitRemap; /* each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] */ + UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 + ULONG ulMemDQ7_0BitRemap; // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] UCHAR ucReservde[4]; UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE_V4 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; /* just for allocation, real number of blocks is in ucNumOfVRAMModule; */ - ATOM_INIT_REG_BLOCK asMemPatch; /* for allocation */ - /* ATOM_INIT_REG_BLOCK aMemAdjust; */ -} ATOM_VRAM_INFO_V4; + ATOM_VRAM_MODULE_V4 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; + ATOM_INIT_REG_BLOCK asMemPatch; // for allocation + // ATOM_INIT_REG_BLOCK aMemAdjust; +}ATOM_VRAM_INFO_V4; -typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO { +typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR aVID_PinsShift[9]; /* 8 bit strap maximum+terminator */ -} ATOM_VRAM_GPIO_DETECTION_INFO; + UCHAR aVID_PinsShift[9]; //8 bit strap maximum+terminator +}ATOM_VRAM_GPIO_DETECTION_INFO; -typedef struct _ATOM_MEMORY_TRAINING_INFO { + +typedef struct _ATOM_MEMORY_TRAINING_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucTrainingLoop; UCHAR ucReserved[3]; ATOM_INIT_REG_BLOCK asMemTrainingSetting; -} ATOM_MEMORY_TRAINING_INFO; +}ATOM_MEMORY_TRAINING_INFO; -typedef struct SW_I2C_CNTL_DATA_PARAMETERS { + +typedef struct SW_I2C_CNTL_DATA_PARAMETERS +{ UCHAR ucControl; UCHAR ucData; UCHAR ucSatus; @@ -4058,11 +4968,12 @@ typedef struct SW_I2C_CNTL_DATA_PARAMETERS { #define SW_I2C_CNTL_DATA_PS_ALLOCATION SW_I2C_CNTL_DATA_PARAMETERS -typedef struct _SW_I2C_IO_DATA_PARAMETERS { +typedef struct _SW_I2C_IO_DATA_PARAMETERS +{ USHORT GPIO_Info; UCHAR ucAct; UCHAR ucData; -} SW_I2C_IO_DATA_PARAMETERS; + } SW_I2C_IO_DATA_PARAMETERS; #define SW_I2C_IO_DATA_PS_ALLOCATION SW_I2C_IO_DATA_PARAMETERS @@ -4087,23 +4998,26 @@ typedef struct _SW_I2C_IO_DATA_PARAMETERS { #define SW_I2C_CNTL_CLOSE 5 #define SW_I2C_CNTL_WRITE1BIT 6 -/* ==============================VESA definition Portion=============================== */ +//==============================VESA definition Portion=============================== #define VESA_OEM_PRODUCT_REV '01.00' -#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB /* refer to VBE spec p.32, no TTY support */ +#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support #define VESA_MODE_WIN_ATTRIBUTE 7 #define VESA_WIN_SIZE 64 -typedef struct _PTR_32_BIT_STRUCTURE { +typedef struct _PTR_32_BIT_STRUCTURE +{ USHORT Offset16; USHORT Segment16; } PTR_32_BIT_STRUCTURE; -typedef union _PTR_32_BIT_UNION { +typedef union _PTR_32_BIT_UNION +{ PTR_32_BIT_STRUCTURE SegmentOffset; ULONG Ptr32_Bit; } PTR_32_BIT_UNION; -typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE { +typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE +{ UCHAR VbeSignature[4]; USHORT VbeVersion; PTR_32_BIT_UNION OemStringPtr; @@ -4112,7 +5026,9 @@ typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE { USHORT TotalMemory; } VBE_1_2_INFO_BLOCK_UPDATABLE; -typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE { + +typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE +{ VBE_1_2_INFO_BLOCK_UPDATABLE CommonBlock; USHORT OemSoftRev; PTR_32_BIT_UNION OemVendorNamePtr; @@ -4120,18 +5036,21 @@ typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE { PTR_32_BIT_UNION OemProductRevPtr; } VBE_2_0_INFO_BLOCK_UPDATABLE; -typedef union _VBE_VERSION_UNION { +typedef union _VBE_VERSION_UNION +{ VBE_2_0_INFO_BLOCK_UPDATABLE VBE_2_0_InfoBlock; VBE_1_2_INFO_BLOCK_UPDATABLE VBE_1_2_InfoBlock; } VBE_VERSION_UNION; -typedef struct _VBE_INFO_BLOCK { +typedef struct _VBE_INFO_BLOCK +{ VBE_VERSION_UNION UpdatableVBE_Info; UCHAR Reserved[222]; UCHAR OemData[256]; } VBE_INFO_BLOCK; -typedef struct _VBE_FP_INFO { +typedef struct _VBE_FP_INFO +{ USHORT HSize; USHORT VSize; USHORT FPType; @@ -4144,65 +5063,66 @@ typedef struct _VBE_FP_INFO { UCHAR Reserved[14]; } VBE_FP_INFO; -typedef struct _VESA_MODE_INFO_BLOCK { -/* Mandatory information for all VBE revisions */ - USHORT ModeAttributes; /* dw ? ; mode attributes */ - UCHAR WinAAttributes; /* db ? ; window A attributes */ - UCHAR WinBAttributes; /* db ? ; window B attributes */ - USHORT WinGranularity; /* dw ? ; window granularity */ - USHORT WinSize; /* dw ? ; window size */ - USHORT WinASegment; /* dw ? ; window A start segment */ - USHORT WinBSegment; /* dw ? ; window B start segment */ - ULONG WinFuncPtr; /* dd ? ; real mode pointer to window function */ - USHORT BytesPerScanLine; /* dw ? ; bytes per scan line */ +typedef struct _VESA_MODE_INFO_BLOCK +{ +// Mandatory information for all VBE revisions + USHORT ModeAttributes; // dw ? ; mode attributes + UCHAR WinAAttributes; // db ? ; window A attributes + UCHAR WinBAttributes; // db ? ; window B attributes + USHORT WinGranularity; // dw ? ; window granularity + USHORT WinSize; // dw ? ; window size + USHORT WinASegment; // dw ? ; window A start segment + USHORT WinBSegment; // dw ? ; window B start segment + ULONG WinFuncPtr; // dd ? ; real mode pointer to window function + USHORT BytesPerScanLine;// dw ? ; bytes per scan line -/* ; Mandatory information for VBE 1.2 and above */ - USHORT XResolution; /* dw ? ; horizontal resolution in pixels or characters */ - USHORT YResolution; /* dw ? ; vertical resolution in pixels or characters */ - UCHAR XCharSize; /* db ? ; character cell width in pixels */ - UCHAR YCharSize; /* db ? ; character cell height in pixels */ - UCHAR NumberOfPlanes; /* db ? ; number of memory planes */ - UCHAR BitsPerPixel; /* db ? ; bits per pixel */ - UCHAR NumberOfBanks; /* db ? ; number of banks */ - UCHAR MemoryModel; /* db ? ; memory model type */ - UCHAR BankSize; /* db ? ; bank size in KB */ - UCHAR NumberOfImagePages; /* db ? ; number of images */ - UCHAR ReservedForPageFunction; /* db 1 ; reserved for page function */ +//; Mandatory information for VBE 1.2 and above + USHORT XResolution; // dw ? ; horizontal resolution in pixels or characters + USHORT YResolution; // dw ? ; vertical resolution in pixels or characters + UCHAR XCharSize; // db ? ; character cell width in pixels + UCHAR YCharSize; // db ? ; character cell height in pixels + UCHAR NumberOfPlanes; // db ? ; number of memory planes + UCHAR BitsPerPixel; // db ? ; bits per pixel + UCHAR NumberOfBanks; // db ? ; number of banks + UCHAR MemoryModel; // db ? ; memory model type + UCHAR BankSize; // db ? ; bank size in KB + UCHAR NumberOfImagePages;// db ? ; number of images + UCHAR ReservedForPageFunction;//db 1 ; reserved for page function -/* ; Direct Color fields(required for direct/6 and YUV/7 memory models) */ - UCHAR RedMaskSize; /* db ? ; size of direct color red mask in bits */ - UCHAR RedFieldPosition; /* db ? ; bit position of lsb of red mask */ - UCHAR GreenMaskSize; /* db ? ; size of direct color green mask in bits */ - UCHAR GreenFieldPosition; /* db ? ; bit position of lsb of green mask */ - UCHAR BlueMaskSize; /* db ? ; size of direct color blue mask in bits */ - UCHAR BlueFieldPosition; /* db ? ; bit position of lsb of blue mask */ - UCHAR RsvdMaskSize; /* db ? ; size of direct color reserved mask in bits */ - UCHAR RsvdFieldPosition; /* db ? ; bit position of lsb of reserved mask */ - UCHAR DirectColorModeInfo; /* db ? ; direct color mode attributes */ +//; Direct Color fields(required for direct/6 and YUV/7 memory models) + UCHAR RedMaskSize; // db ? ; size of direct color red mask in bits + UCHAR RedFieldPosition; // db ? ; bit position of lsb of red mask + UCHAR GreenMaskSize; // db ? ; size of direct color green mask in bits + UCHAR GreenFieldPosition; // db ? ; bit position of lsb of green mask + UCHAR BlueMaskSize; // db ? ; size of direct color blue mask in bits + UCHAR BlueFieldPosition; // db ? ; bit position of lsb of blue mask + UCHAR RsvdMaskSize; // db ? ; size of direct color reserved mask in bits + UCHAR RsvdFieldPosition; // db ? ; bit position of lsb of reserved mask + UCHAR DirectColorModeInfo;// db ? ; direct color mode attributes -/* ; Mandatory information for VBE 2.0 and above */ - ULONG PhysBasePtr; /* dd ? ; physical address for flat memory frame buffer */ - ULONG Reserved_1; /* dd 0 ; reserved - always set to 0 */ - USHORT Reserved_2; /* dw 0 ; reserved - always set to 0 */ +//; Mandatory information for VBE 2.0 and above + ULONG PhysBasePtr; // dd ? ; physical address for flat memory frame buffer + ULONG Reserved_1; // dd 0 ; reserved - always set to 0 + USHORT Reserved_2; // dw 0 ; reserved - always set to 0 -/* ; Mandatory information for VBE 3.0 and above */ - USHORT LinBytesPerScanLine; /* dw ? ; bytes per scan line for linear modes */ - UCHAR BnkNumberOfImagePages; /* db ? ; number of images for banked modes */ - UCHAR LinNumberOfImagPages; /* db ? ; number of images for linear modes */ - UCHAR LinRedMaskSize; /* db ? ; size of direct color red mask(linear modes) */ - UCHAR LinRedFieldPosition; /* db ? ; bit position of lsb of red mask(linear modes) */ - UCHAR LinGreenMaskSize; /* db ? ; size of direct color green mask(linear modes) */ - UCHAR LinGreenFieldPosition; /* db ? ; bit position of lsb of green mask(linear modes) */ - UCHAR LinBlueMaskSize; /* db ? ; size of direct color blue mask(linear modes) */ - UCHAR LinBlueFieldPosition; /* db ? ; bit position of lsb of blue mask(linear modes) */ - UCHAR LinRsvdMaskSize; /* db ? ; size of direct color reserved mask(linear modes) */ - UCHAR LinRsvdFieldPosition; /* db ? ; bit position of lsb of reserved mask(linear modes) */ - ULONG MaxPixelClock; /* dd ? ; maximum pixel clock(in Hz) for graphics mode */ - UCHAR Reserved; /* db 190 dup (0) */ +//; Mandatory information for VBE 3.0 and above + USHORT LinBytesPerScanLine; // dw ? ; bytes per scan line for linear modes + UCHAR BnkNumberOfImagePages;// db ? ; number of images for banked modes + UCHAR LinNumberOfImagPages; // db ? ; number of images for linear modes + UCHAR LinRedMaskSize; // db ? ; size of direct color red mask(linear modes) + UCHAR LinRedFieldPosition; // db ? ; bit position of lsb of red mask(linear modes) + UCHAR LinGreenMaskSize; // db ? ; size of direct color green mask(linear modes) + UCHAR LinGreenFieldPosition;// db ? ; bit position of lsb of green mask(linear modes) + UCHAR LinBlueMaskSize; // db ? ; size of direct color blue mask(linear modes) + UCHAR LinBlueFieldPosition; // db ? ; bit position of lsb of blue mask(linear modes) + UCHAR LinRsvdMaskSize; // db ? ; size of direct color reserved mask(linear modes) + UCHAR LinRsvdFieldPosition; // db ? ; bit position of lsb of reserved mask(linear modes) + ULONG MaxPixelClock; // dd ? ; maximum pixel clock(in Hz) for graphics mode + UCHAR Reserved; // db 190 dup (0) } VESA_MODE_INFO_BLOCK; -/* BIOS function CALLS */ -#define ATOM_BIOS_EXTENDED_FUNCTION_CODE 0xA0 /* ATI Extended Function code */ +// BIOS function CALLS +#define ATOM_BIOS_EXTENDED_FUNCTION_CODE 0xA0 // ATI Extended Function code #define ATOM_BIOS_FUNCTION_COP_MODE 0x00 #define ATOM_BIOS_FUNCTION_SHORT_QUERY1 0x04 #define ATOM_BIOS_FUNCTION_SHORT_QUERY2 0x05 @@ -4219,98 +5139,133 @@ typedef struct _VESA_MODE_INFO_BLOCK { #define ATOM_BIOS_FUNCTION_OLD_DEVICE_SWITCH 0x84 #define ATOM_BIOS_FUNCTION_HW_ICON 0x8A #define ATOM_BIOS_FUNCTION_SET_CMOS 0x8B -#define SUB_FUNCTION_UPDATE_DISPLAY_INFO 0x8000 /* Sub function 80 */ -#define SUB_FUNCTION_UPDATE_EXPANSION_INFO 0x8100 /* Sub function 80 */ +#define SUB_FUNCTION_UPDATE_DISPLAY_INFO 0x8000 // Sub function 80 +#define SUB_FUNCTION_UPDATE_EXPANSION_INFO 0x8100 // Sub function 80 #define ATOM_BIOS_FUNCTION_DISPLAY_INFO 0x8D #define ATOM_BIOS_FUNCTION_DEVICE_ON_OFF 0x8E #define ATOM_BIOS_FUNCTION_VIDEO_STATE 0x8F -#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE 0x0300 /* Sub function 03 */ -#define ATOM_SUB_FUNCTION_GET_LIDSTATE 0x0700 /* Sub function 7 */ -#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE 0x1400 /* Notify caller the current thermal state */ -#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300 /* Notify caller the current critical state */ -#define ATOM_SUB_FUNCTION_SET_LIDSTATE 0x8500 /* Sub function 85 */ -#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900 /* Sub function 89 */ -#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT 0x9400 /* Notify caller that ADC is supported */ +#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE 0x0300 // Sub function 03 +#define ATOM_SUB_FUNCTION_GET_LIDSTATE 0x0700 // Sub function 7 +#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE 0x1400 // Notify caller the current thermal state +#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300 // Notify caller the current critical state +#define ATOM_SUB_FUNCTION_SET_LIDSTATE 0x8500 // Sub function 85 +#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900// Sub function 89 +#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT 0x9400 // Notify caller that ADC is supported + -#define ATOM_BIOS_FUNCTION_VESA_DPMS 0x4F10 /* Set DPMS */ -#define ATOM_SUB_FUNCTION_SET_DPMS 0x0001 /* BL: Sub function 01 */ -#define ATOM_SUB_FUNCTION_GET_DPMS 0x0002 /* BL: Sub function 02 */ -#define ATOM_PARAMETER_VESA_DPMS_ON 0x0000 /* BH Parameter for DPMS ON. */ -#define ATOM_PARAMETER_VESA_DPMS_STANDBY 0x0100 /* BH Parameter for DPMS STANDBY */ -#define ATOM_PARAMETER_VESA_DPMS_SUSPEND 0x0200 /* BH Parameter for DPMS SUSPEND */ -#define ATOM_PARAMETER_VESA_DPMS_OFF 0x0400 /* BH Parameter for DPMS OFF */ -#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON 0x0800 /* BH Parameter for DPMS REDUCE ON (NOT SUPPORTED) */ +#define ATOM_BIOS_FUNCTION_VESA_DPMS 0x4F10 // Set DPMS +#define ATOM_SUB_FUNCTION_SET_DPMS 0x0001 // BL: Sub function 01 +#define ATOM_SUB_FUNCTION_GET_DPMS 0x0002 // BL: Sub function 02 +#define ATOM_PARAMETER_VESA_DPMS_ON 0x0000 // BH Parameter for DPMS ON. +#define ATOM_PARAMETER_VESA_DPMS_STANDBY 0x0100 // BH Parameter for DPMS STANDBY +#define ATOM_PARAMETER_VESA_DPMS_SUSPEND 0x0200 // BH Parameter for DPMS SUSPEND +#define ATOM_PARAMETER_VESA_DPMS_OFF 0x0400 // BH Parameter for DPMS OFF +#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON 0x0800 // BH Parameter for DPMS REDUCE ON (NOT SUPPORTED) #define ATOM_BIOS_RETURN_CODE_MASK 0x0000FF00L #define ATOM_BIOS_REG_HIGH_MASK 0x0000FF00L #define ATOM_BIOS_REG_LOW_MASK 0x000000FFL -/* structure used for VBIOS only */ +// structure used for VBIOS only -/* DispOutInfoTable */ -typedef struct _ASIC_TRANSMITTER_INFO { +//DispOutInfoTable +typedef struct _ASIC_TRANSMITTER_INFO +{ USHORT usTransmitterObjId; USHORT usSupportDevice; UCHAR ucTransmitterCmdTblId; UCHAR ucConfig; - UCHAR ucEncoderID; /* available 1st encoder ( default ) */ - UCHAR ucOptionEncoderID; /* available 2nd encoder ( optional ) */ + UCHAR ucEncoderID; //available 1st encoder ( default ) + UCHAR ucOptionEncoderID; //available 2nd encoder ( optional ) UCHAR uc2ndEncoderID; UCHAR ucReserved; -} ASIC_TRANSMITTER_INFO; +}ASIC_TRANSMITTER_INFO; -typedef struct _ASIC_ENCODER_INFO { +typedef struct _ASIC_ENCODER_INFO +{ UCHAR ucEncoderID; UCHAR ucEncoderConfig; USHORT usEncoderCmdTblId; -} ASIC_ENCODER_INFO; +}ASIC_ENCODER_INFO; -typedef struct _ATOM_DISP_OUT_INFO { +typedef struct _ATOM_DISP_OUT_INFO +{ + ATOM_COMMON_TABLE_HEADER sHeader; + USHORT ptrTransmitterInfo; + USHORT ptrEncoderInfo; + ASIC_TRANSMITTER_INFO asTransmitterInfo[1]; + ASIC_ENCODER_INFO asEncoderInfo[1]; +}ATOM_DISP_OUT_INFO; + +typedef struct _ATOM_DISP_OUT_INFO_V2 +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT ptrTransmitterInfo; USHORT ptrEncoderInfo; + USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary. ASIC_TRANSMITTER_INFO asTransmitterInfo[1]; ASIC_ENCODER_INFO asEncoderInfo[1]; -} ATOM_DISP_OUT_INFO; +}ATOM_DISP_OUT_INFO_V2; -/* DispDevicePriorityInfo */ -typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO { +// DispDevicePriorityInfo +typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT asDevicePriority[16]; -} ATOM_DISPLAY_DEVICE_PRIORITY_INFO; +}ATOM_DISPLAY_DEVICE_PRIORITY_INFO; -/* ProcessAuxChannelTransactionTable */ -typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS { +//ProcessAuxChannelTransactionTable +typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS +{ USHORT lpAuxRequest; USHORT lpDataOut; UCHAR ucChannelID; - union { + union + { UCHAR ucReplyStatus; UCHAR ucDelay; }; UCHAR ucDataOutLen; UCHAR ucReserved; -} PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS; +}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS; + +//ProcessAuxChannelTransactionTable +typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 +{ + USHORT lpAuxRequest; + USHORT lpDataOut; + UCHAR ucChannelID; + union + { + UCHAR ucReplyStatus; + UCHAR ucDelay; + }; + UCHAR ucDataOutLen; + UCHAR ucHPD_ID; //=0: HPD1, =1: HPD2, =2: HPD3, =3: HPD4, =4: HPD5, =5: HPD6 +}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2; #define PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS -/* GetSinkType */ +//GetSinkType -typedef struct _DP_ENCODER_SERVICE_PARAMETERS { +typedef struct _DP_ENCODER_SERVICE_PARAMETERS +{ USHORT ucLinkClock; - union { - UCHAR ucConfig; /* for DP training command */ - UCHAR ucI2cId; /* use for GET_SINK_TYPE command */ + union + { + UCHAR ucConfig; // for DP training command + UCHAR ucI2cId; // use for GET_SINK_TYPE command }; UCHAR ucAction; UCHAR ucStatus; UCHAR ucLaneNum; UCHAR ucReserved[2]; -} DP_ENCODER_SERVICE_PARAMETERS; +}DP_ENCODER_SERVICE_PARAMETERS; -/* ucAction */ +// ucAction #define ATOM_DP_ACTION_GET_SINK_TYPE 0x01 +/* obselete */ #define ATOM_DP_ACTION_TRAINING_START 0x02 #define ATOM_DP_ACTION_TRAINING_COMPLETE 0x03 #define ATOM_DP_ACTION_TRAINING_PATTERN_SEL 0x04 @@ -4318,7 +5273,7 @@ typedef struct _DP_ENCODER_SERVICE_PARAMETERS { #define ATOM_DP_ACTION_GET_VSWING_PREEMP 0x06 #define ATOM_DP_ACTION_BLANKING 0x07 -/* ucConfig */ +// ucConfig #define ATOM_DP_CONFIG_ENCODER_SEL_MASK 0x03 #define ATOM_DP_CONFIG_DIG1_ENCODER 0x00 #define ATOM_DP_CONFIG_DIG2_ENCODER 0x01 @@ -4326,14 +5281,14 @@ typedef struct _DP_ENCODER_SERVICE_PARAMETERS { #define ATOM_DP_CONFIG_LINK_SEL_MASK 0x04 #define ATOM_DP_CONFIG_LINK_A 0x00 #define ATOM_DP_CONFIG_LINK_B 0x04 - +/* /obselete */ #define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS -/* DP_TRAINING_TABLE */ +// DP_TRAINING_TABLE #define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR #define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) -#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 16) -#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 24) +#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 16 ) +#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 24 ) #define DPCD_SET_TRAINING_PATTERN2_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 32) #define DPCD_GET_LINKRATE_LANENUM_SS_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 40) #define DPCD_GET_LANE_STATUS_ADJUST_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 48) @@ -4341,11 +5296,14 @@ typedef struct _DP_ENCODER_SERVICE_PARAMETERS { #define DP_I2C_AUX_DDC_WRITE_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 64) #define DP_I2C_AUX_DDC_READ_START_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 72) #define DP_I2C_AUX_DDC_READ_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 76) -#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 80) +#define DP_I2C_AUX_DDC_WRITE_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 80) +#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 84) -typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS { +typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS +{ UCHAR ucI2CSpeed; - union { + union + { UCHAR ucRegIndex; UCHAR ucStatus; }; @@ -4354,79 +5312,115 @@ typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS { UCHAR ucTransBytes; UCHAR ucSlaveAddr; UCHAR ucLineNumber; -} PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS; +}PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS; #define PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS -/* ucFlag */ +//ucFlag #define HW_I2C_WRITE 1 #define HW_I2C_READ 0 +#define I2C_2BYTE_ADDR 0x02 -/****************************************************************************/ -/* Portion VI: Definitinos being oboselete */ +typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 +{ + UCHAR ucHWBlkInst; // HW block instance, 0, 1, 2, ... + UCHAR ucReserved[3]; +}SET_HWBLOCK_INSTANCE_PARAMETER_V2; + +#define HWBLKINST_INSTANCE_MASK 0x07 +#define HWBLKINST_HWBLK_MASK 0xF0 +#define HWBLKINST_HWBLK_SHIFT 0x04 + +//ucHWBlock +#define SELECT_DISP_ENGINE 0 +#define SELECT_DISP_PLL 1 +#define SELECT_DCIO_UNIPHY_LINK0 2 +#define SELECT_DCIO_UNIPHY_LINK1 3 +#define SELECT_DCIO_IMPCAL 4 +#define SELECT_DCIO_DIG 6 +#define SELECT_CRTC_PIXEL_RATE 7 + +/****************************************************************************/ +//Portion VI: Definitinos for vbios MC scratch registers that driver used /****************************************************************************/ -/* ========================================================================================== */ -/* Remove the definitions below when driver is ready! */ -typedef struct _ATOM_DAC_INFO { +#define MC_MISC0__MEMORY_TYPE_MASK 0xF0000000 +#define MC_MISC0__MEMORY_TYPE__GDDR1 0x10000000 +#define MC_MISC0__MEMORY_TYPE__DDR2 0x20000000 +#define MC_MISC0__MEMORY_TYPE__GDDR3 0x30000000 +#define MC_MISC0__MEMORY_TYPE__GDDR4 0x40000000 +#define MC_MISC0__MEMORY_TYPE__GDDR5 0x50000000 +#define MC_MISC0__MEMORY_TYPE__DDR3 0xB0000000 + +/****************************************************************************/ +//Portion VI: Definitinos being oboselete +/****************************************************************************/ + +//========================================================================================== +//Remove the definitions below when driver is ready! +typedef struct _ATOM_DAC_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMaxFrequency; /* in 10kHz unit */ + USHORT usMaxFrequency; // in 10kHz unit USHORT usReserved; -} ATOM_DAC_INFO; +}ATOM_DAC_INFO; -typedef struct _COMPASSIONATE_DATA { + +typedef struct _COMPASSIONATE_DATA +{ ATOM_COMMON_TABLE_HEADER sHeader; - /* ============================== DAC1 portion */ + //============================== DAC1 portion UCHAR ucDAC1_BG_Adjustment; UCHAR ucDAC1_DAC_Adjustment; USHORT usDAC1_FORCE_Data; - /* ============================== DAC2 portion */ + //============================== DAC2 portion UCHAR ucDAC2_CRT2_BG_Adjustment; UCHAR ucDAC2_CRT2_DAC_Adjustment; USHORT usDAC2_CRT2_FORCE_Data; USHORT usDAC2_CRT2_MUX_RegisterIndex; - UCHAR ucDAC2_CRT2_MUX_RegisterInfo; /* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */ + UCHAR ucDAC2_CRT2_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low UCHAR ucDAC2_NTSC_BG_Adjustment; UCHAR ucDAC2_NTSC_DAC_Adjustment; USHORT usDAC2_TV1_FORCE_Data; USHORT usDAC2_TV1_MUX_RegisterIndex; - UCHAR ucDAC2_TV1_MUX_RegisterInfo; /* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */ + UCHAR ucDAC2_TV1_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low UCHAR ucDAC2_CV_BG_Adjustment; UCHAR ucDAC2_CV_DAC_Adjustment; USHORT usDAC2_CV_FORCE_Data; USHORT usDAC2_CV_MUX_RegisterIndex; - UCHAR ucDAC2_CV_MUX_RegisterInfo; /* Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low */ + UCHAR ucDAC2_CV_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low UCHAR ucDAC2_PAL_BG_Adjustment; UCHAR ucDAC2_PAL_DAC_Adjustment; USHORT usDAC2_TV2_FORCE_Data; -} COMPASSIONATE_DATA; +}COMPASSIONATE_DATA; /****************************Supported Device Info Table Definitions**********************/ -/* ucConnectInfo: */ -/* [7:4] - connector type */ -/* = 1 - VGA connector */ -/* = 2 - DVI-I */ -/* = 3 - DVI-D */ -/* = 4 - DVI-A */ -/* = 5 - SVIDEO */ -/* = 6 - COMPOSITE */ -/* = 7 - LVDS */ -/* = 8 - DIGITAL LINK */ -/* = 9 - SCART */ -/* = 0xA - HDMI_type A */ -/* = 0xB - HDMI_type B */ -/* = 0xE - Special case1 (DVI+DIN) */ -/* Others=TBD */ -/* [3:0] - DAC Associated */ -/* = 0 - no DAC */ -/* = 1 - DACA */ -/* = 2 - DACB */ -/* = 3 - External DAC */ -/* Others=TBD */ -/* */ +// ucConnectInfo: +// [7:4] - connector type +// = 1 - VGA connector +// = 2 - DVI-I +// = 3 - DVI-D +// = 4 - DVI-A +// = 5 - SVIDEO +// = 6 - COMPOSITE +// = 7 - LVDS +// = 8 - DIGITAL LINK +// = 9 - SCART +// = 0xA - HDMI_type A +// = 0xB - HDMI_type B +// = 0xE - Special case1 (DVI+DIN) +// Others=TBD +// [3:0] - DAC Associated +// = 0 - no DAC +// = 1 - DACA +// = 2 - DACB +// = 3 - External DAC +// Others=TBD +// -typedef struct _ATOM_CONNECTOR_INFO { +typedef struct _ATOM_CONNECTOR_INFO +{ #if ATOM_BIG_ENDIAN UCHAR bfConnectorType:4; UCHAR bfAssociatedDAC:4; @@ -4434,90 +5428,109 @@ typedef struct _ATOM_CONNECTOR_INFO { UCHAR bfAssociatedDAC:4; UCHAR bfConnectorType:4; #endif -} ATOM_CONNECTOR_INFO; +}ATOM_CONNECTOR_INFO; -typedef union _ATOM_CONNECTOR_INFO_ACCESS { +typedef union _ATOM_CONNECTOR_INFO_ACCESS +{ ATOM_CONNECTOR_INFO sbfAccess; UCHAR ucAccess; -} ATOM_CONNECTOR_INFO_ACCESS; +}ATOM_CONNECTOR_INFO_ACCESS; -typedef struct _ATOM_CONNECTOR_INFO_I2C { +typedef struct _ATOM_CONNECTOR_INFO_I2C +{ ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo; ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; -} ATOM_CONNECTOR_INFO_I2C; +}ATOM_CONNECTOR_INFO_I2C; -typedef struct _ATOM_SUPPORTED_DEVICES_INFO { + +typedef struct _ATOM_SUPPORTED_DEVICES_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usDeviceSupport; ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO]; -} ATOM_SUPPORTED_DEVICES_INFO; +}ATOM_SUPPORTED_DEVICES_INFO; #define NO_INT_SRC_MAPPED 0xFF -typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP { +typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP +{ UCHAR ucIntSrcBitmap; -} ATOM_CONNECTOR_INC_SRC_BITMAP; +}ATOM_CONNECTOR_INC_SRC_BITMAP; -typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2 { +typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2 +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usDeviceSupport; ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; - ATOM_CONNECTOR_INC_SRC_BITMAP - asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; -} ATOM_SUPPORTED_DEVICES_INFO_2; + ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; +}ATOM_SUPPORTED_DEVICES_INFO_2; -typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 { +typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usDeviceSupport; ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE]; ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE]; -} ATOM_SUPPORTED_DEVICES_INFO_2d1; +}ATOM_SUPPORTED_DEVICES_INFO_2d1; #define ATOM_SUPPORTED_DEVICES_INFO_LAST ATOM_SUPPORTED_DEVICES_INFO_2d1 -typedef struct _ATOM_MISC_CONTROL_INFO { + + +typedef struct _ATOM_MISC_CONTROL_INFO +{ USHORT usFrequency; - UCHAR ucPLL_ChargePump; /* PLL charge-pump gain control */ - UCHAR ucPLL_DutyCycle; /* PLL duty cycle control */ - UCHAR ucPLL_VCO_Gain; /* PLL VCO gain control */ - UCHAR ucPLL_VoltageSwing; /* PLL driver voltage swing control */ -} ATOM_MISC_CONTROL_INFO; + UCHAR ucPLL_ChargePump; // PLL charge-pump gain control + UCHAR ucPLL_DutyCycle; // PLL duty cycle control + UCHAR ucPLL_VCO_Gain; // PLL VCO gain control + UCHAR ucPLL_VoltageSwing; // PLL driver voltage swing control +}ATOM_MISC_CONTROL_INFO; + #define ATOM_MAX_MISC_INFO 4 -typedef struct _ATOM_TMDS_INFO { +typedef struct _ATOM_TMDS_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMaxFrequency; /* in 10Khz */ + USHORT usMaxFrequency; // in 10Khz ATOM_MISC_CONTROL_INFO asMiscInfo[ATOM_MAX_MISC_INFO]; -} ATOM_TMDS_INFO; +}ATOM_TMDS_INFO; -typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE { - UCHAR ucTVStandard; /* Same as TV standards defined above, */ + +typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE +{ + UCHAR ucTVStandard; //Same as TV standards defined above, UCHAR ucPadding[1]; -} ATOM_ENCODER_ANALOG_ATTRIBUTE; +}ATOM_ENCODER_ANALOG_ATTRIBUTE; -typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE { - UCHAR ucAttribute; /* Same as other digital encoder attributes defined above */ +typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE +{ + UCHAR ucAttribute; //Same as other digital encoder attributes defined above UCHAR ucPadding[1]; -} ATOM_ENCODER_DIGITAL_ATTRIBUTE; +}ATOM_ENCODER_DIGITAL_ATTRIBUTE; -typedef union _ATOM_ENCODER_ATTRIBUTE { +typedef union _ATOM_ENCODER_ATTRIBUTE +{ ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib; ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib; -} ATOM_ENCODER_ATTRIBUTE; +}ATOM_ENCODER_ATTRIBUTE; -typedef struct _DVO_ENCODER_CONTROL_PARAMETERS { + +typedef struct _DVO_ENCODER_CONTROL_PARAMETERS +{ USHORT usPixelClock; USHORT usEncoderID; - UCHAR ucDeviceType; /* Use ATOM_DEVICE_xxx1_Index to indicate device type only. */ - UCHAR ucAction; /* ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT */ + UCHAR ucDeviceType; //Use ATOM_DEVICE_xxx1_Index to indicate device type only. + UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT ATOM_ENCODER_ATTRIBUTE usDevAttr; -} DVO_ENCODER_CONTROL_PARAMETERS; +}DVO_ENCODER_CONTROL_PARAMETERS; -typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION { +typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION +{ DVO_ENCODER_CONTROL_PARAMETERS sDVOEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; /* Caller doesn't need to init this portion */ -} DVO_ENCODER_CONTROL_PS_ALLOCATION; + WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion +}DVO_ENCODER_CONTROL_PS_ALLOCATION; + #define ATOM_XTMDS_ASIC_SI164_ID 1 #define ATOM_XTMDS_ASIC_SI178_ID 2 @@ -4526,27 +5539,30 @@ typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION { #define ATOM_XTMDS_SUPPORTED_DUALLINK 0x00000002 #define ATOM_XTMDS_MVPU_FPGA 0x00000004 -typedef struct _ATOM_XTMDS_INFO { + +typedef struct _ATOM_XTMDS_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; USHORT usSingleLinkMaxFrequency; - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; /* Point the ID on which I2C is used to control external chip */ + ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //Point the ID on which I2C is used to control external chip UCHAR ucXtransimitterID; - UCHAR ucSupportedLink; /* Bit field, bit0=1, single link supported;bit1=1,dual link supported */ - UCHAR ucSequnceAlterID; /* Even with the same external TMDS asic, it's possible that the program seqence alters */ - /* due to design. This ID is used to alert driver that the sequence is not "standard"! */ - UCHAR ucMasterAddress; /* Address to control Master xTMDS Chip */ - UCHAR ucSlaveAddress; /* Address to control Slave xTMDS Chip */ -} ATOM_XTMDS_INFO; + UCHAR ucSupportedLink; // Bit field, bit0=1, single link supported;bit1=1,dual link supported + UCHAR ucSequnceAlterID; // Even with the same external TMDS asic, it's possible that the program seqence alters + // due to design. This ID is used to alert driver that the sequence is not "standard"! + UCHAR ucMasterAddress; // Address to control Master xTMDS Chip + UCHAR ucSlaveAddress; // Address to control Slave xTMDS Chip +}ATOM_XTMDS_INFO; -typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS { - UCHAR ucEnable; /* ATOM_ENABLE=On or ATOM_DISABLE=Off */ - UCHAR ucDevice; /* ATOM_DEVICE_DFP1_INDEX.... */ +typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS +{ + UCHAR ucEnable; // ATOM_ENABLE=On or ATOM_DISABLE=Off + UCHAR ucDevice; // ATOM_DEVICE_DFP1_INDEX.... UCHAR ucPadding[2]; -} DFP_DPMS_STATUS_CHANGE_PARAMETERS; +}DFP_DPMS_STATUS_CHANGE_PARAMETERS; /****************************Legacy Power Play Table Definitions **********************/ -/* Definitions for ulPowerPlayMiscInfo */ +//Definitions for ulPowerPlayMiscInfo #define ATOM_PM_MISCINFO_SPLIT_CLOCK 0x00000000L #define ATOM_PM_MISCINFO_USING_MCLK_SRC 0x00000001L #define ATOM_PM_MISCINFO_USING_SCLK_SRC 0x00000002L @@ -4558,7 +5574,7 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS { #define ATOM_PM_MISCINFO_ENGINE_CLOCK_CONTRL_EN 0x00000020L #define ATOM_PM_MISCINFO_MEMORY_CLOCK_CONTRL_EN 0x00000040L -#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE 0x00000080L /* When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program */ +#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE 0x00000080L //When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program #define ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN 0x00000100L #define ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN 0x00000200L @@ -4574,17 +5590,17 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS { #define ATOM_PM_MISCINFO_POWER_SAVING_MODE 0x00040000L #define ATOM_PM_MISCINFO_THERMAL_DIODE_MODE 0x00080000L -#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK 0x00300000L /* 0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved */ +#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK 0x00300000L //0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved #define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT 20 #define ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE 0x00400000L #define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2 0x00800000L #define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4 0x01000000L -#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN 0x02000000L /* When set, Dynamic */ -#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN 0x04000000L /* When set, Dynamic */ -#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN 0x08000000L /* When set, This mode is for acceleated 3D mode */ +#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN 0x02000000L //When set, Dynamic +#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN 0x04000000L //When set, Dynamic +#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN 0x08000000L //When set, This mode is for acceleated 3D mode -#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK 0x70000000L /* 1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) */ +#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK 0x70000000L //1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) #define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_SHIFT 28 #define ATOM_PM_MISCINFO_ENABLE_BACK_BIAS 0x80000000L @@ -4594,55 +5610,59 @@ typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS { #define ATOM_PM_MISCINFO2_FS3D_OVERDRIVE_INFO 0x00000008L #define ATOM_PM_MISCINFO2_FORCEDLOWPWR_MODE 0x00000010L #define ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN 0x00000020L -#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE 0x00000040L /* If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. */ - /* If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback */ +#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE 0x00000040L //If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. + //If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback #define ATOM_PM_MISCINFO2_NOT_VALID_ON_DC 0x00000080L #define ATOM_PM_MISCINFO2_STUTTER_MODE_EN 0x00000100L #define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE 0x00000200L -/* ucTableFormatRevision=1 */ -/* ucTableContentRevision=1 */ -typedef struct _ATOM_POWERMODE_INFO { - ULONG ulMiscInfo; /* The power level should be arranged in ascending order */ - ULONG ulReserved1; /* must set to 0 */ - ULONG ulReserved2; /* must set to 0 */ +//ucTableFormatRevision=1 +//ucTableContentRevision=1 +typedef struct _ATOM_POWERMODE_INFO +{ + ULONG ulMiscInfo; //The power level should be arranged in ascending order + ULONG ulReserved1; // must set to 0 + ULONG ulReserved2; // must set to 0 USHORT usEngineClock; USHORT usMemoryClock; - UCHAR ucVoltageDropIndex; /* index to GPIO table */ - UCHAR ucSelectedPanel_RefreshRate; /* panel refresh rate */ + UCHAR ucVoltageDropIndex; // index to GPIO table + UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate UCHAR ucMinTemperature; UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; /* number of PCIE lanes */ -} ATOM_POWERMODE_INFO; + UCHAR ucNumPciELanes; // number of PCIE lanes +}ATOM_POWERMODE_INFO; -/* ucTableFormatRevision=2 */ -/* ucTableContentRevision=1 */ -typedef struct _ATOM_POWERMODE_INFO_V2 { - ULONG ulMiscInfo; /* The power level should be arranged in ascending order */ +//ucTableFormatRevision=2 +//ucTableContentRevision=1 +typedef struct _ATOM_POWERMODE_INFO_V2 +{ + ULONG ulMiscInfo; //The power level should be arranged in ascending order ULONG ulMiscInfo2; ULONG ulEngineClock; ULONG ulMemoryClock; - UCHAR ucVoltageDropIndex; /* index to GPIO table */ - UCHAR ucSelectedPanel_RefreshRate; /* panel refresh rate */ + UCHAR ucVoltageDropIndex; // index to GPIO table + UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate UCHAR ucMinTemperature; UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; /* number of PCIE lanes */ -} ATOM_POWERMODE_INFO_V2; + UCHAR ucNumPciELanes; // number of PCIE lanes +}ATOM_POWERMODE_INFO_V2; -/* ucTableFormatRevision=2 */ -/* ucTableContentRevision=2 */ -typedef struct _ATOM_POWERMODE_INFO_V3 { - ULONG ulMiscInfo; /* The power level should be arranged in ascending order */ +//ucTableFormatRevision=2 +//ucTableContentRevision=2 +typedef struct _ATOM_POWERMODE_INFO_V3 +{ + ULONG ulMiscInfo; //The power level should be arranged in ascending order ULONG ulMiscInfo2; ULONG ulEngineClock; ULONG ulMemoryClock; - UCHAR ucVoltageDropIndex; /* index to Core (VDDC) votage table */ - UCHAR ucSelectedPanel_RefreshRate; /* panel refresh rate */ + UCHAR ucVoltageDropIndex; // index to Core (VDDC) votage table + UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate UCHAR ucMinTemperature; UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; /* number of PCIE lanes */ - UCHAR ucVDDCI_VoltageDropIndex; /* index to VDDCI votage table */ -} ATOM_POWERMODE_INFO_V3; + UCHAR ucNumPciELanes; // number of PCIE lanes + UCHAR ucVDDCI_VoltageDropIndex; // index to VDDCI votage table +}ATOM_POWERMODE_INFO_V3; + #define ATOM_MAX_NUMBEROF_POWER_BLOCK 8 @@ -4655,9 +5675,11 @@ typedef struct _ATOM_POWERMODE_INFO_V3 { #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_MUA6649 0x04 #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM64 0x05 #define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_F75375 0x06 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512 0x07 /* Andigilog */ +#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512 0x07 // Andigilog -typedef struct _ATOM_POWERPLAY_INFO { + +typedef struct _ATOM_POWERPLAY_INFO +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucOverdriveThermalController; UCHAR ucOverdriveI2cLine; @@ -4666,9 +5688,10 @@ typedef struct _ATOM_POWERPLAY_INFO { UCHAR ucSizeOfPowerModeEntry; UCHAR ucNumOfPowerModeEntries; ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -} ATOM_POWERPLAY_INFO; +}ATOM_POWERPLAY_INFO; -typedef struct _ATOM_POWERPLAY_INFO_V2 { +typedef struct _ATOM_POWERPLAY_INFO_V2 +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucOverdriveThermalController; UCHAR ucOverdriveI2cLine; @@ -4677,9 +5700,10 @@ typedef struct _ATOM_POWERPLAY_INFO_V2 { UCHAR ucSizeOfPowerModeEntry; UCHAR ucNumOfPowerModeEntries; ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -} ATOM_POWERPLAY_INFO_V2; +}ATOM_POWERPLAY_INFO_V2; -typedef struct _ATOM_POWERPLAY_INFO_V3 { +typedef struct _ATOM_POWERPLAY_INFO_V3 +{ ATOM_COMMON_TABLE_HEADER sHeader; UCHAR ucOverdriveThermalController; UCHAR ucOverdriveI2cLine; @@ -4688,7 +5712,7 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 { UCHAR ucSizeOfPowerModeEntry; UCHAR ucNumOfPowerModeEntries; ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -} ATOM_POWERPLAY_INFO_V3; +}ATOM_POWERPLAY_INFO_V3; /* New PPlib */ /**************************************************************************/ @@ -4891,7 +5915,8 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO /**************************************************************************/ -/* Following definitions are for compatiblity issue in different SW components. */ + +// Following definitions are for compatiblity issue in different SW components. #define ATOM_MASTER_DATA_TABLE_REVISION 0x01 #define Object_Info Object_Header #define AdjustARB_SEQ MC_InitParameter @@ -4903,10 +5928,11 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO #define DispDevicePriorityInfo SaveRestoreInfo #define DispOutInfo TV_VideoMode + #define ATOM_ENCODER_OBJECT_TABLE ATOM_OBJECT_TABLE #define ATOM_CONNECTOR_OBJECT_TABLE ATOM_OBJECT_TABLE -/* New device naming, remove them when both DAL/VBIOS is ready */ +//New device naming, remove them when both DAL/VBIOS is ready #define DFP2I_OUTPUT_CONTROL_PARAMETERS CRT1_OUTPUT_CONTROL_PARAMETERS #define DFP2I_OUTPUT_CONTROL_PS_ALLOCATION DFP2I_OUTPUT_CONTROL_PARAMETERS @@ -4984,12 +6010,56 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO #define CRT1OutputControl DAC1OutputControl #define CRT2OutputControl DAC2OutputControl -/* These two lines will be removed for sure in a few days, will follow up with Michael V. */ +//These two lines will be removed for sure in a few days, will follow up with Michael V. #define EnableLVDS_SS EnableSpreadSpectrumOnPPLL #define ENABLE_LVDS_SS_PARAMETERS_V3 ENABLE_SPREAD_SPECTRUM_ON_PPLL +//#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L +//#define ATOM_S2_LCD1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE +//#define ATOM_S2_TV1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE +//#define ATOM_S2_DFP1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE +//#define ATOM_S2_CRT2_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE + +#define ATOM_S6_ACC_REQ_TV2 0x00400000L +#define ATOM_DEVICE_TV2_INDEX 0x00000006 +#define ATOM_DEVICE_TV2_SUPPORT (0x1L << ATOM_DEVICE_TV2_INDEX) +#define ATOM_S0_TV2 0x00100000L +#define ATOM_S3_TV2_ACTIVE ATOM_S3_DFP6_ACTIVE +#define ATOM_S3_TV2_CRTC_ACTIVE ATOM_S3_DFP6_CRTC_ACTIVE + +// +#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L +#define ATOM_S2_LCD1_DPMS_STATE 0x00020000L +#define ATOM_S2_TV1_DPMS_STATE 0x00040000L +#define ATOM_S2_DFP1_DPMS_STATE 0x00080000L +#define ATOM_S2_CRT2_DPMS_STATE 0x00100000L +#define ATOM_S2_LCD2_DPMS_STATE 0x00200000L +#define ATOM_S2_TV2_DPMS_STATE 0x00400000L +#define ATOM_S2_DFP2_DPMS_STATE 0x00800000L +#define ATOM_S2_CV_DPMS_STATE 0x01000000L +#define ATOM_S2_DFP3_DPMS_STATE 0x02000000L +#define ATOM_S2_DFP4_DPMS_STATE 0x04000000L +#define ATOM_S2_DFP5_DPMS_STATE 0x08000000L + +#define ATOM_S2_CRT1_DPMS_STATEb2 0x01 +#define ATOM_S2_LCD1_DPMS_STATEb2 0x02 +#define ATOM_S2_TV1_DPMS_STATEb2 0x04 +#define ATOM_S2_DFP1_DPMS_STATEb2 0x08 +#define ATOM_S2_CRT2_DPMS_STATEb2 0x10 +#define ATOM_S2_LCD2_DPMS_STATEb2 0x20 +#define ATOM_S2_TV2_DPMS_STATEb2 0x40 +#define ATOM_S2_DFP2_DPMS_STATEb2 0x80 +#define ATOM_S2_CV_DPMS_STATEb3 0x01 +#define ATOM_S2_DFP3_DPMS_STATEb3 0x02 +#define ATOM_S2_DFP4_DPMS_STATEb3 0x04 +#define ATOM_S2_DFP5_DPMS_STATEb3 0x08 + +#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3 0x20 +#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40 +#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3 0x80 + /*********************************************************************************/ -#pragma pack() /* BIOS data must use byte aligment */ +#pragma pack() // BIOS data must use byte aligment #endif /* _ATOMBIOS_H */ diff --git a/drivers/video/drm/radeon/atombios_crtc.c b/drivers/video/drm/radeon/atombios_crtc.c index 6337c458e7..ac0ab70905 100644 --- a/drivers/video/drm/radeon/atombios_crtc.c +++ b/drivers/video/drm/radeon/atombios_crtc.c @@ -245,19 +245,25 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) switch (mode) { case DRM_MODE_DPMS_ON: - atombios_enable_crtc(crtc, 1); + atombios_enable_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev)) - atombios_enable_crtc_memreq(crtc, 1); - atombios_blank_crtc(crtc, 0); + atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); + atombios_blank_crtc(crtc, ATOM_DISABLE); + /* XXX re-enable when interrupt support is added */ + if (!ASIC_IS_DCE4(rdev)) + drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - atombios_blank_crtc(crtc, 1); + /* XXX re-enable when interrupt support is added */ + if (!ASIC_IS_DCE4(rdev)) + drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); + atombios_blank_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev)) - atombios_enable_crtc_memreq(crtc, 0); - atombios_enable_crtc(crtc, 0); + atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); + atombios_enable_crtc(crtc, ATOM_DISABLE); break; } } @@ -347,6 +353,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +union atom_enable_ss { + ENABLE_LVDS_SS_PARAMETERS legacy; + ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; +}; + static void atombios_set_ss(struct drm_crtc *crtc, int enable) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); @@ -356,11 +367,14 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) struct radeon_encoder *radeon_encoder = NULL; struct radeon_encoder_atom_dig *dig = NULL; int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); - ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; - ENABLE_LVDS_SS_PARAMETERS legacy_args; + union atom_enable_ss args; uint16_t percentage = 0; uint8_t type = 0, step = 0, delay = 0, range = 0; + /* XXX add ss support for DCE4 */ + if (ASIC_IS_DCE4(rdev)) + return; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { radeon_encoder = to_radeon_encoder(encoder); @@ -384,29 +398,28 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) if (!radeon_encoder) return; + memset(&args, 0, sizeof(args)); if (ASIC_IS_AVIVO(rdev)) { - memset(&args, 0, sizeof(args)); - args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); - args.ucSpreadSpectrumType = type; - args.ucSpreadSpectrumStep = step; - args.ucSpreadSpectrumDelay = delay; - args.ucSpreadSpectrumRange = range; - args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; - args.ucEnable = enable; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + args.v1.usSpreadSpectrumPercentage = cpu_to_le16(percentage); + args.v1.ucSpreadSpectrumType = type; + args.v1.ucSpreadSpectrumStep = step; + args.v1.ucSpreadSpectrumDelay = delay; + args.v1.ucSpreadSpectrumRange = range; + args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; + args.v1.ucEnable = enable; } else { - memset(&legacy_args, 0, sizeof(legacy_args)); - legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); - legacy_args.ucSpreadSpectrumType = type; - legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; - legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; - legacy_args.ucEnable = enable; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args); + args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage); + args.legacy.ucSpreadSpectrumType = type; + args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; + args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; + args.legacy.ucEnable = enable; } + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } union adjust_pixel_clock { ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; + ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; }; static u32 atombios_adjust_pll(struct drm_crtc *crtc, @@ -418,10 +431,24 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, struct drm_encoder *encoder = NULL; struct radeon_encoder *radeon_encoder = NULL; u32 adjusted_clock = mode->clock; + int encoder_mode = 0; /* reset the pll flags */ pll->flags = 0; + /* select the PLL algo */ + if (ASIC_IS_AVIVO(rdev)) { + if (radeon_new_pll == 0) + pll->algo = PLL_ALGO_LEGACY; + else + pll->algo = PLL_ALGO_NEW; + } else { + if (radeon_new_pll == 1) + pll->algo = PLL_ALGO_NEW; + else + pll->algo = PLL_ALGO_LEGACY; + } + if (ASIC_IS_AVIVO(rdev)) { if ((rdev->family == CHIP_RS600) || (rdev->family == CHIP_RS690) || @@ -446,10 +473,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { radeon_encoder = to_radeon_encoder(encoder); + encoder_mode = atombios_get_encoder_mode(encoder); if (ASIC_IS_AVIVO(rdev)) { /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) adjusted_clock = mode->clock * 2; + /* LVDS PLL quirks */ + if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + pll->algo = dig->pll_algo; + } } else { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; @@ -466,14 +499,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, */ if (ASIC_IS_DCE3(rdev)) { union adjust_pixel_clock args; - struct radeon_encoder_atom_dig *dig; u8 frev, crev; int index; - if (!radeon_encoder->enc_priv) - return adjusted_clock; - dig = radeon_encoder->enc_priv; - index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); @@ -487,12 +515,51 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, case 2: args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); args.v1.ucTransmitterID = radeon_encoder->encoder_id; - args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); + args.v1.ucEncodeMode = encoder_mode; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; break; + case 3: + args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; + args.v3.sInput.ucEncodeMode = encoder_mode; + args.v3.sInput.ucDispPllConfig = 0; + if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + if (encoder_mode == ATOM_ENCODER_MODE_DP) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_COHERENT_MODE; + else { + if (dig->coherent_mode) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_COHERENT_MODE; + if (mode->clock > 165000) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_DUAL_LINK; + } + } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + /* may want to enable SS on DP/eDP eventually */ + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_SS_ENABLE; + if (mode->clock > 165000) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_DUAL_LINK; + } + atom_execute_table(rdev->mode_info.atom_context, + index, (uint32_t *)&args); + adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; + if (args.v3.sOutput.ucRefDiv) { + pll->flags |= RADEON_PLL_USE_REF_DIV; + pll->reference_div = args.v3.sOutput.ucRefDiv; + } + if (args.v3.sOutput.ucPostDiv) { + pll->flags |= RADEON_PLL_USE_POST_DIV; + pll->post_div = args.v3.sOutput.ucPostDiv; + } + break; default: DRM_ERROR("Unknown table version %d %d\n", frev, crev); return adjusted_clock; @@ -511,9 +578,47 @@ union set_pixel_clock { PIXEL_CLOCK_PARAMETERS v1; PIXEL_CLOCK_PARAMETERS_V2 v2; PIXEL_CLOCK_PARAMETERS_V3 v3; + PIXEL_CLOCK_PARAMETERS_V5 v5; }; -void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) +static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + u8 frev, crev; + int index; + union set_pixel_clock args; + + memset(&args, 0, sizeof(args)); + + index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); + atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, + &crev); + + switch (frev) { + case 1: + switch (crev) { + case 5: + /* if the default dcpll clock is specified, + * SetPixelClock provides the dividers + */ + args.v5.ucCRTC = ATOM_CRTC_INVALID; + args.v5.usPixelClock = rdev->clock.default_dispclk; + args.v5.ucPpll = ATOM_DCPLL; + break; + default: + DRM_ERROR("Unknown table version %d %d\n", frev, crev); + return; + } + break; + default: + DRM_ERROR("Unknown table version %d %d\n", frev, crev); + return; + } + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + +static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; @@ -527,12 +632,14 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; struct radeon_pll *pll; u32 adjusted_clock; + int encoder_mode = 0; memset(&args, 0, sizeof(args)); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { radeon_encoder = to_radeon_encoder(encoder); + encoder_mode = atombios_get_encoder_mode(encoder); break; } } @@ -540,24 +647,22 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) if (!radeon_encoder) return; - if (radeon_crtc->crtc_id == 0) + switch (radeon_crtc->pll_id) { + case ATOM_PPLL1: pll = &rdev->clock.p1pll; - else + break; + case ATOM_PPLL2: pll = &rdev->clock.p2pll; + break; + case ATOM_DCPLL: + case ATOM_PPLL_INVALID: + pll = &rdev->clock.dcpll; + break; + } /* adjust pixel clock as needed */ adjusted_clock = atombios_adjust_pll(crtc, mode, pll); - if (ASIC_IS_AVIVO(rdev)) { - if (radeon_new_pll) - radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, - &fb_div, &frac_fb_div, - &ref_div, &post_div); - else - radeon_compute_pll(pll, adjusted_clock, &pll_clock, - &fb_div, &frac_fb_div, - &ref_div, &post_div); - } else radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, &ref_div, &post_div); @@ -574,8 +679,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) args.v1.usFbDiv = cpu_to_le16(fb_div); args.v1.ucFracFbDiv = frac_fb_div; args.v1.ucPostDiv = post_div; - args.v1.ucPpll = - radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; + args.v1.ucPpll = radeon_crtc->pll_id; args.v1.ucCRTC = radeon_crtc->crtc_id; args.v1.ucRefDivSrc = 1; break; @@ -585,8 +689,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) args.v2.usFbDiv = cpu_to_le16(fb_div); args.v2.ucFracFbDiv = frac_fb_div; args.v2.ucPostDiv = post_div; - args.v2.ucPpll = - radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; + args.v2.ucPpll = radeon_crtc->pll_id; args.v2.ucCRTC = radeon_crtc->crtc_id; args.v2.ucRefDivSrc = 1; break; @@ -596,12 +699,22 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) args.v3.usFbDiv = cpu_to_le16(fb_div); args.v3.ucFracFbDiv = frac_fb_div; args.v3.ucPostDiv = post_div; - args.v3.ucPpll = - radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; - args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2); + args.v3.ucPpll = radeon_crtc->pll_id; + args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2); args.v3.ucTransmitterId = radeon_encoder->encoder_id; - args.v3.ucEncoderMode = - atombios_get_encoder_mode(encoder); + args.v3.ucEncoderMode = encoder_mode; + break; + case 5: + args.v5.ucCRTC = radeon_crtc->crtc_id; + args.v5.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v5.ucRefDiv = ref_div; + args.v5.usFbDiv = cpu_to_le16(fb_div); + args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); + args.v5.ucPostDiv = post_div; + args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ + args.v5.ucTransmitterID = radeon_encoder->encoder_id; + args.v5.ucEncoderMode = encoder_mode; + args.v5.ucPpll = radeon_crtc->pll_id; break; default: DRM_ERROR("Unknown table version %d %d\n", frev, crev); @@ -616,11 +729,143 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_framebuffer *radeon_fb; + struct drm_gem_object *obj; + struct radeon_bo *rbo; + uint64_t fb_location; + uint32_t fb_format, fb_pitch_pixels, tiling_flags; + int r; + + /* no fb bound */ + if (!crtc->fb) { + DRM_DEBUG("No FB bound\n"); + return 0; + } + + radeon_fb = to_radeon_framebuffer(crtc->fb); + + /* Pin framebuffer & get tilling informations */ + obj = radeon_fb->obj; + rbo = obj->driver_private; + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) + return r; + r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); + if (unlikely(r != 0)) { + radeon_bo_unreserve(rbo); + return -EINVAL; + } + radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); + radeon_bo_unreserve(rbo); + + switch (crtc->fb->bits_per_pixel) { + case 8: + fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | + EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); + break; + case 15: + fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | + EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555)); + break; + case 16: + fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | + EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); + break; + case 24: + case 32: + fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | + EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); + break; + default: + DRM_ERROR("Unsupported screen depth %d\n", + crtc->fb->bits_per_pixel); + return -EINVAL; + } + + switch (radeon_crtc->crtc_id) { + case 0: + WREG32(AVIVO_D1VGA_CONTROL, 0); + break; + case 1: + WREG32(AVIVO_D2VGA_CONTROL, 0); + break; + case 2: + WREG32(EVERGREEN_D3VGA_CONTROL, 0); + break; + case 3: + WREG32(EVERGREEN_D4VGA_CONTROL, 0); + break; + case 4: + WREG32(EVERGREEN_D5VGA_CONTROL, 0); + break; + case 5: + WREG32(EVERGREEN_D6VGA_CONTROL, 0); + break; + default: + break; + } + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, + upper_32_bits(fb_location)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, + upper_32_bits(fb_location)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); + WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); + + WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); + WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); + + fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); + WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); + WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); + + WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, + crtc->mode.vdisplay); + x &= ~3; + y &= ~1; + WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, + (x << 16) | y); + WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, + (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + + if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, + EVERGREEN_INTERLEAVE_EN); + else + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + + if (old_fb && old_fb != crtc->fb) { + radeon_fb = to_radeon_framebuffer(old_fb); + rbo = radeon_fb->obj->driver_private; + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) + return r; + radeon_bo_unpin(rbo); + radeon_bo_unreserve(rbo); + } + + /* Bytes per pixel may have changed */ + radeon_bandwidth_update(rdev); + + return 0; +} + static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { - ENTER(); - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; @@ -746,8 +991,6 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, /* Bytes per pixel may have changed */ radeon_bandwidth_update(rdev); - LEAVE(); - return 0; } @@ -757,7 +1000,9 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; - if (ASIC_IS_AVIVO(rdev)) + if (ASIC_IS_DCE4(rdev)) + return evergreen_crtc_set_base(crtc, x, y, old_fb); + else if (ASIC_IS_AVIVO(rdev)) return avivo_crtc_set_base(crtc, x, y, old_fb); else return radeon_crtc_set_base(crtc, x, y, old_fb); @@ -787,6 +1032,46 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) } } +static int radeon_atom_pick_pll(struct drm_crtc *crtc) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + struct drm_encoder *test_encoder; + struct drm_crtc *test_crtc; + uint32_t pll_in_use = 0; + + if (ASIC_IS_DCE4(rdev)) { + /* if crtc is driving DP and we have an ext clock, use that */ + list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { + if (test_encoder->crtc && (test_encoder->crtc == crtc)) { + if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) { + if (rdev->clock.dp_extclk) + return ATOM_PPLL_INVALID; + } + } + } + + /* otherwise, pick one of the plls */ + list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { + struct radeon_crtc *radeon_test_crtc; + + if (crtc == test_crtc) + continue; + + radeon_test_crtc = to_radeon_crtc(test_crtc); + if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && + (radeon_test_crtc->pll_id <= ATOM_PPLL2)) + pll_in_use |= (1 << radeon_test_crtc->pll_id); + } + if (!(pll_in_use & 1)) + return ATOM_PPLL1; + return ATOM_PPLL2; + } else + return radeon_crtc->crtc_id; + +} + int atombios_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -798,19 +1083,27 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, /* TODO color tiling */ + /* pick pll */ + radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); + atombios_set_ss(crtc, 0); + /* always set DCPLL */ + if (ASIC_IS_DCE4(rdev)) + atombios_crtc_set_dcpll(crtc); atombios_crtc_set_pll(crtc, adjusted_mode); atombios_set_ss(crtc, 1); - atombios_crtc_set_timing(crtc, adjusted_mode); - if (ASIC_IS_AVIVO(rdev)) - atombios_crtc_set_base(crtc, x, y, old_fb); + if (ASIC_IS_DCE4(rdev)) + atombios_set_crtc_dtd_timing(crtc, adjusted_mode); + else if (ASIC_IS_AVIVO(rdev)) + atombios_crtc_set_timing(crtc, adjusted_mode); else { + atombios_crtc_set_timing(crtc, adjusted_mode); if (radeon_crtc->crtc_id == 0) atombios_set_crtc_dtd_timing(crtc, adjusted_mode); - atombios_crtc_set_base(crtc, x, y, old_fb); radeon_legacy_atom_fixup(crtc); } + atombios_crtc_set_base(crtc, x, y, old_fb); atombios_overscan_setup(crtc, mode, adjusted_mode); atombios_scaler_setup(crtc); return 0; @@ -827,14 +1120,14 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, static void atombios_crtc_prepare(struct drm_crtc *crtc) { - atombios_lock_crtc(crtc, 1); + atombios_lock_crtc(crtc, ATOM_ENABLE); atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); } static void atombios_crtc_commit(struct drm_crtc *crtc) { atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); - atombios_lock_crtc(crtc, 0); + atombios_lock_crtc(crtc, ATOM_DISABLE); } static const struct drm_crtc_helper_funcs atombios_helper_funcs = { @@ -850,8 +1143,37 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { void radeon_atombios_init_crtc(struct drm_device *dev, struct radeon_crtc *radeon_crtc) { + struct radeon_device *rdev = dev->dev_private; + + if (ASIC_IS_DCE4(rdev)) { + switch (radeon_crtc->crtc_id) { + case 0: + default: + radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET; + break; + case 1: + radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET; + break; + case 2: + radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET; + break; + case 3: + radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET; + break; + case 4: + radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET; + break; + case 5: + radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET; + break; + } + } else { if (radeon_crtc->crtc_id == 1) radeon_crtc->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; + else + radeon_crtc->crtc_offset = 0; + } + radeon_crtc->pll_id = -1; drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); } diff --git a/drivers/video/drm/radeon/atombios_dp.c b/drivers/video/drm/radeon/atombios_dp.c index af3e4836d0..a1f2d79f74 100644 --- a/drivers/video/drm/radeon/atombios_dp.c +++ b/drivers/video/drm/radeon/atombios_dp.c @@ -321,6 +321,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], train_set[lane] = v | p; } +union aux_channel_transaction { + PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; +}; /* radeon aux chan functions */ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, @@ -329,7 +333,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, { struct drm_device *dev = chan->dev; struct radeon_device *rdev = dev->dev_private; - PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; + union aux_channel_transaction args; int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); unsigned char *base; int retry_count = 0; @@ -341,31 +345,33 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, retry: memcpy(base, req_bytes, num_bytes); - args.lpAuxRequest = 0; - args.lpDataOut = 16; - args.ucDataOutLen = 0; - args.ucChannelID = chan->rec.i2c_id; - args.ucDelay = delay / 10; + args.v1.lpAuxRequest = 0; + args.v1.lpDataOut = 16; + args.v1.ucDataOutLen = 0; + args.v1.ucChannelID = chan->rec.i2c_id; + args.v1.ucDelay = delay / 10; + if (ASIC_IS_DCE4(rdev)) + args.v2.ucHPD_ID = chan->rec.hpd_id; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (args.ucReplyStatus && !args.ucDataOutLen) { - if (args.ucReplyStatus == 0x20 && retry_count++ < 10) + if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) { + if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10) goto retry; DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], - chan->rec.i2c_id, args.ucReplyStatus, retry_count); + chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count); return false; } - if (args.ucDataOutLen && read_byte && read_buf_len) { - if (read_buf_len < args.ucDataOutLen) { + if (args.v1.ucDataOutLen && read_byte && read_buf_len) { + if (read_buf_len < args.v1.ucDataOutLen) { DRM_ERROR("Buffer to small for return answer %d %d\n", - read_buf_len, args.ucDataOutLen); + read_buf_len, args.v1.ucDataOutLen); return false; } { - int len = min(read_buf_len, args.ucDataOutLen); + int len = min(read_buf_len, args.v1.ucDataOutLen); memcpy(read_byte, base + 16, len); } } @@ -626,12 +632,19 @@ void dp_link_train(struct drm_encoder *encoder, dp_set_link_bw_lanes(radeon_connector, link_configuration); /* disable downspread on the sink */ dp_set_downspread(radeon_connector, 0); + if (ASIC_IS_DCE4(rdev)) { + /* start training on the source */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START); + /* set training pattern 1 on the source */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1); + } else { /* start training on the source */ radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, dig_connector->dp_clock, enc_id, 0); /* set training pattern 1 on the source */ radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, dig_connector->dp_clock, enc_id, 0); + } /* set initial vs/emph */ memset(train_set, 0, 4); @@ -691,6 +704,9 @@ void dp_link_train(struct drm_encoder *encoder, /* set training pattern 2 on the sink */ dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); /* set training pattern 2 on the source */ + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2); + else radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, dig_connector->dp_clock, enc_id, 1); @@ -729,7 +745,11 @@ void dp_link_train(struct drm_encoder *encoder, >> DP_TRAIN_PRE_EMPHASIS_SHIFT); /* disable the training pattern on the sink */ - dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE); + else + radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, + dig_connector->dp_clock, enc_id, 0); radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, dig_connector->dp_clock, enc_id, 0); diff --git a/drivers/video/drm/radeon/avivod.h b/drivers/video/drm/radeon/avivod.h index 89d332a769..d8360cf326 100644 --- a/drivers/video/drm/radeon/avivod.h +++ b/drivers/video/drm/radeon/avivod.h @@ -30,11 +30,13 @@ #define D1CRTC_CONTROL 0x6080 #define CRTC_EN (1 << 0) +#define D1CRTC_STATUS 0x609c #define D1CRTC_UPDATE_LOCK 0x60E8 #define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 #define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 #define D2CRTC_CONTROL 0x6880 +#define D2CRTC_STATUS 0x689c #define D2CRTC_UPDATE_LOCK 0x68E8 #define D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 #define D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 diff --git a/drivers/video/drm/radeon/evergreen.c b/drivers/video/drm/radeon/evergreen.c new file mode 100644 index 0000000000..e5b73d3399 --- /dev/null +++ b/drivers/video/drm/radeon/evergreen.c @@ -0,0 +1,720 @@ +/* + * Copyright 2010 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Alex Deucher + */ +#include +//#include +#include "drmP.h" +#include "radeon.h" +#include "radeon_drm.h" +#include "rv770d.h" +#include "atom.h" +#include "avivod.h" +#include "evergreen_reg.h" + +static void evergreen_gpu_init(struct radeon_device *rdev); +void evergreen_fini(struct radeon_device *rdev); + +bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) +{ + bool connected = false; + /* XXX */ + return connected; +} + +void evergreen_hpd_set_polarity(struct radeon_device *rdev, + enum radeon_hpd_id hpd) +{ + /* XXX */ +} + +void evergreen_hpd_init(struct radeon_device *rdev) +{ + /* XXX */ +} + + +void evergreen_bandwidth_update(struct radeon_device *rdev) +{ + /* XXX */ +} + +void evergreen_hpd_fini(struct radeon_device *rdev) +{ + /* XXX */ +} + +static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) +{ + unsigned i; + u32 tmp; + + for (i = 0; i < rdev->usec_timeout; i++) { + /* read MC_STATUS */ + tmp = RREG32(SRBM_STATUS) & 0x1F00; + if (!tmp) + return 0; + udelay(1); + } + return -1; +} + +/* + * GART + */ +int evergreen_pcie_gart_enable(struct radeon_device *rdev) +{ + u32 tmp; + int r, i; + + if (rdev->gart.table.vram.robj == NULL) { + dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); + return -EINVAL; + } + r = radeon_gart_table_vram_pin(rdev); + if (r) + return r; + radeon_gart_restore(rdev); + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | + ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | + EFFECTIVE_L2_QUEUE_SIZE(7)); + WREG32(VM_L2_CNTL2, 0); + WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); + /* Setup TLB control */ + tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | + SYSTEM_ACCESS_MODE_NOT_IN_SYS | + SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | + EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); + WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); + WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); + WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); + WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, + (u32)(rdev->dummy_page.addr >> 12)); + for (i = 1; i < 7; i++) + WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); + + r600_pcie_gart_tlb_flush(rdev); + rdev->gart.ready = true; + return 0; +} + +void evergreen_pcie_gart_disable(struct radeon_device *rdev) +{ + u32 tmp; + int i, r; + + /* Disable all tables */ + for (i = 0; i < 7; i++) + WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); + + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | + EFFECTIVE_L2_QUEUE_SIZE(7)); + WREG32(VM_L2_CNTL2, 0); + WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); + /* Setup TLB control */ + tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); + WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); + if (rdev->gart.table.vram.robj) { + r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); + if (likely(r == 0)) { + radeon_bo_kunmap(rdev->gart.table.vram.robj); + radeon_bo_unpin(rdev->gart.table.vram.robj); + radeon_bo_unreserve(rdev->gart.table.vram.robj); + } + } +} + +void evergreen_pcie_gart_fini(struct radeon_device *rdev) +{ + evergreen_pcie_gart_disable(rdev); + radeon_gart_table_vram_free(rdev); + radeon_gart_fini(rdev); +} + + +void evergreen_agp_enable(struct radeon_device *rdev) +{ + u32 tmp; + int i; + + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | + ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | + EFFECTIVE_L2_QUEUE_SIZE(7)); + WREG32(VM_L2_CNTL2, 0); + WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); + /* Setup TLB control */ + tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | + SYSTEM_ACCESS_MODE_NOT_IN_SYS | + SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | + EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); + WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); + WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); + for (i = 0; i < 7; i++) + WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); +} + +static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) +{ + save->vga_control[0] = RREG32(D1VGA_CONTROL); + save->vga_control[1] = RREG32(D2VGA_CONTROL); + save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); + save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); + save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); + save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); + save->vga_render_control = RREG32(VGA_RENDER_CONTROL); + save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); + save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); + save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); + save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); + save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); + save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); + save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + + /* Stop all video */ + WREG32(VGA_RENDER_CONTROL, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + + WREG32(D1VGA_CONTROL, 0); + WREG32(D2VGA_CONTROL, 0); + WREG32(EVERGREEN_D3VGA_CONTROL, 0); + WREG32(EVERGREEN_D4VGA_CONTROL, 0); + WREG32(EVERGREEN_D5VGA_CONTROL, 0); + WREG32(EVERGREEN_D6VGA_CONTROL, 0); +} + +static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) +{ + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); + /* Unlock host access */ + WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); + mdelay(1); + /* Restore video state */ + WREG32(D1VGA_CONTROL, save->vga_control[0]); + WREG32(D2VGA_CONTROL, save->vga_control[1]); + WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); + WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); + WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); + WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + WREG32(VGA_RENDER_CONTROL, save->vga_render_control); +} + +static void evergreen_mc_program(struct radeon_device *rdev) +{ + struct evergreen_mc_save save; + u32 tmp; + int i, j; + + /* Initialize HDP */ + for (i = 0, j = 0; i < 32; i++, j += 0x18) { + WREG32((0x2c14 + j), 0x00000000); + WREG32((0x2c18 + j), 0x00000000); + WREG32((0x2c1c + j), 0x00000000); + WREG32((0x2c20 + j), 0x00000000); + WREG32((0x2c24 + j), 0x00000000); + } + WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); + + evergreen_mc_stop(rdev, &save); + if (evergreen_mc_wait_for_idle(rdev)) { + dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); + } + /* Lockout access through VGA aperture*/ + WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); + /* Update configuration */ + if (rdev->flags & RADEON_IS_AGP) { + if (rdev->mc.vram_start < rdev->mc.gtt_start) { + /* VRAM before AGP */ + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, + rdev->mc.vram_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, + rdev->mc.gtt_end >> 12); + } else { + /* VRAM after AGP */ + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, + rdev->mc.gtt_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, + rdev->mc.vram_end >> 12); + } + } else { + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, + rdev->mc.vram_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, + rdev->mc.vram_end >> 12); + } + WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); + tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; + tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); + WREG32(MC_VM_FB_LOCATION, tmp); + WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); + WREG32(HDP_NONSURFACE_INFO, (2 << 7)); + WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); + if (rdev->flags & RADEON_IS_AGP) { + WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); + WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); + WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); + } else { + WREG32(MC_VM_AGP_BASE, 0); + WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); + WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); + } + if (evergreen_mc_wait_for_idle(rdev)) { + dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); + } + evergreen_mc_resume(rdev, &save); + /* we need to own VRAM, so turn off the VGA renderer here + * to stop it overwriting our objects */ + rv515_vga_render_disable(rdev); +} + +#if 0 +/* + * CP. + */ +static void evergreen_cp_stop(struct radeon_device *rdev) +{ + /* XXX */ +} + + +static int evergreen_cp_load_microcode(struct radeon_device *rdev) +{ + /* XXX */ + + return 0; +} + + +/* + * Core functions + */ +static u32 evergreen_get_tile_pipe_to_backend_map(u32 num_tile_pipes, + u32 num_backends, + u32 backend_disable_mask) +{ + u32 backend_map = 0; + + return backend_map; +} +#endif + +static void evergreen_gpu_init(struct radeon_device *rdev) +{ + /* XXX */ +} + +int evergreen_mc_init(struct radeon_device *rdev) +{ + fixed20_12 a; + u32 tmp; + int chansize, numchan; + + /* Get VRAM informations */ + rdev->mc.vram_is_ddr = true; + tmp = RREG32(MC_ARB_RAMCFG); + if (tmp & CHANSIZE_OVERRIDE) { + chansize = 16; + } else if (tmp & CHANSIZE_MASK) { + chansize = 64; + } else { + chansize = 32; + } + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + default: + numchan = 1; + break; + case 1: + numchan = 2; + break; + case 2: + numchan = 4; + break; + case 3: + numchan = 8; + break; + } + rdev->mc.vram_width = numchan * chansize; + /* Could aper size report 0 ? */ + rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); + rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + /* Setup GPU memory space */ + /* size in MB on evergreen */ + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.visible_vram_size = rdev->mc.aper_size; + /* FIXME remove this once we support unmappable VRAM */ + if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { + rdev->mc.mc_vram_size = rdev->mc.aper_size; + rdev->mc.real_vram_size = rdev->mc.aper_size; + } + r600_vram_gtt_location(rdev, &rdev->mc); + /* FIXME: we should enforce default clock in case GPU is not in + * default setup + */ + a.full = rfixed_const(100); + rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); + rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); + return 0; +} + +int evergreen_gpu_reset(struct radeon_device *rdev) +{ + /* FIXME: implement for evergreen */ + return 0; +} + +static int evergreen_startup(struct radeon_device *rdev) +{ +#if 0 + int r; + + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = r600_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } +#endif + evergreen_mc_program(rdev); +#if 0 + if (rdev->flags & RADEON_IS_AGP) { + evergreem_agp_enable(rdev); + } else { + r = evergreen_pcie_gart_enable(rdev); + if (r) + return r; + } +#endif + evergreen_gpu_init(rdev); +#if 0 + + r = radeon_ring_init(rdev, rdev->cp.ring_size); + if (r) + return r; + r = evergreen_cp_load_microcode(rdev); + if (r) + return r; + r = r600_cp_resume(rdev); + if (r) + return r; + /* write back buffer are not vital so don't worry about failure */ + r600_wb_enable(rdev); +#endif + return 0; +} + +int evergreen_resume(struct radeon_device *rdev) +{ + int r; + + /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, + * posting will perform necessary task to bring back GPU into good + * shape. + */ + /* post card */ + atom_asic_init(rdev->mode_info.atom_context); + /* Initialize clocks */ + r = radeon_clocks_init(rdev); + if (r) { + return r; + } + + r = evergreen_startup(rdev); + if (r) { + DRM_ERROR("r600 startup failed on resume\n"); + return r; + } +#if 0 + r = r600_ib_test(rdev); + if (r) { + DRM_ERROR("radeon: failled testing IB (%d).\n", r); + return r; + } +#endif + return r; + +} + +int evergreen_suspend(struct radeon_device *rdev) +{ +#if 0 + int r; + + /* FIXME: we should wait for ring to be empty */ + r700_cp_stop(rdev); + rdev->cp.ready = false; + r600_wb_disable(rdev); + evergreen_pcie_gart_disable(rdev); + /* unpin shaders bo */ + r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); + if (likely(r == 0)) { + radeon_bo_unpin(rdev->r600_blit.shader_obj); + radeon_bo_unreserve(rdev->r600_blit.shader_obj); + } +#endif + return 0; +} + +static bool evergreen_card_posted(struct radeon_device *rdev) +{ + u32 reg; + + /* first check CRTCs */ + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + if (reg & EVERGREEN_CRTC_MASTER_EN) + return true; + + /* then check MEM_SIZE, in case the crtcs are off */ + if (RREG32(CONFIG_MEMSIZE)) + return true; + + return false; +} + +/* Plan is to move initialization in that function and use + * helper function so that radeon_device_init pretty much + * do nothing more than calling asic specific function. This + * should also allow to remove a bunch of callback function + * like vram_info. + */ +int evergreen_init(struct radeon_device *rdev) +{ + int r; + + r = radeon_dummy_page_init(rdev); + if (r) + return r; + /* This don't do much */ + r = radeon_gem_init(rdev); + if (r) + return r; + /* Read BIOS */ + if (!radeon_get_bios(rdev)) { + if (ASIC_IS_AVIVO(rdev)) + return -EINVAL; + } + /* Must be an ATOMBIOS */ + if (!rdev->is_atom_bios) { + dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); + return -EINVAL; + } + r = radeon_atombios_init(rdev); + if (r) + return r; + /* Post card if necessary */ + if (!evergreen_card_posted(rdev)) { + if (!rdev->bios) { + dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); + return -EINVAL; + } + DRM_INFO("GPU not posted. posting now...\n"); + atom_asic_init(rdev->mode_info.atom_context); + } + /* Initialize scratch registers */ + r600_scratch_init(rdev); + /* Initialize surface registers */ + radeon_surface_init(rdev); + /* Initialize clocks */ + radeon_get_clock_info(rdev->ddev); + r = radeon_clocks_init(rdev); + if (r) + return r; + /* Initialize power management */ + radeon_pm_init(rdev); + /* Fence driver */ + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); + if (r) + radeon_agp_disable(rdev); + } + /* initialize memory controller */ + r = evergreen_mc_init(rdev); + if (r) + return r; + /* Memory manager */ + r = radeon_bo_init(rdev); + if (r) + return r; +#if 0 + r = radeon_irq_kms_init(rdev); + if (r) + return r; + + rdev->cp.ring_obj = NULL; + r600_ring_init(rdev, 1024 * 1024); + + rdev->ih.ring_obj = NULL; + r600_ih_ring_init(rdev, 64 * 1024); + + r = r600_pcie_gart_init(rdev); + if (r) + return r; +#endif + rdev->accel_working = false; + r = evergreen_startup(rdev); + if (r) { + evergreen_suspend(rdev); + /*r600_wb_fini(rdev);*/ + /*radeon_ring_fini(rdev);*/ + /*evergreen_pcie_gart_fini(rdev);*/ + rdev->accel_working = false; + } + if (rdev->accel_working) { + } + return 0; +} + +void evergreen_fini(struct radeon_device *rdev) +{ + evergreen_suspend(rdev); +#if 0 + r600_blit_fini(rdev); + r600_irq_fini(rdev); + radeon_irq_kms_fini(rdev); + radeon_ring_fini(rdev); + r600_wb_fini(rdev); + evergreen_pcie_gart_fini(rdev); +#endif + kfree(rdev->bios); + rdev->bios = NULL; +} diff --git a/drivers/video/drm/radeon/evergreen_reg.h b/drivers/video/drm/radeon/evergreen_reg.h new file mode 100644 index 0000000000..50ad5f0a98 --- /dev/null +++ b/drivers/video/drm/radeon/evergreen_reg.h @@ -0,0 +1,176 @@ +/* + * Copyright 2010 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Alex Deucher + */ +#ifndef __EVERGREEN_REG_H__ +#define __EVERGREEN_REG_H__ + +/* evergreen */ +#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310 +#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324 +#define EVERGREEN_D3VGA_CONTROL 0x3e0 +#define EVERGREEN_D4VGA_CONTROL 0x3e4 +#define EVERGREEN_D5VGA_CONTROL 0x3e8 +#define EVERGREEN_D6VGA_CONTROL 0x3ec + +#define EVERGREEN_P1PLL_SS_CNTL 0x414 +#define EVERGREEN_P2PLL_SS_CNTL 0x454 +# define EVERGREEN_PxPLL_SS_EN (1 << 12) +/* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */ +#define EVERGREEN_GRPH_ENABLE 0x6800 +#define EVERGREEN_GRPH_CONTROL 0x6804 +# define EVERGREEN_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define EVERGREEN_GRPH_DEPTH_8BPP 0 +# define EVERGREEN_GRPH_DEPTH_16BPP 1 +# define EVERGREEN_GRPH_DEPTH_32BPP 2 +# define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define EVERGREEN_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define EVERGREEN_GRPH_FORMAT_ARGB1555 0 +# define EVERGREEN_GRPH_FORMAT_ARGB565 1 +# define EVERGREEN_GRPH_FORMAT_ARGB4444 2 +# define EVERGREEN_GRPH_FORMAT_AI88 3 +# define EVERGREEN_GRPH_FORMAT_MONO16 4 +# define EVERGREEN_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define EVERGREEN_GRPH_FORMAT_ARGB8888 0 +# define EVERGREEN_GRPH_FORMAT_ARGB2101010 1 +# define EVERGREEN_GRPH_FORMAT_32BPP_DIG 2 +# define EVERGREEN_GRPH_FORMAT_8B_ARGB2101010 3 +# define EVERGREEN_GRPH_FORMAT_BGRA1010102 4 +# define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 +# define EVERGREEN_GRPH_FORMAT_RGB111110 6 +# define EVERGREEN_GRPH_FORMAT_BGR101111 7 +#define EVERGREEN_GRPH_SWAP_CONTROL 0x680c +# define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) +# define EVERGREEN_GRPH_ENDIAN_NONE 0 +# define EVERGREEN_GRPH_ENDIAN_8IN16 1 +# define EVERGREEN_GRPH_ENDIAN_8IN32 2 +# define EVERGREEN_GRPH_ENDIAN_8IN64 3 +# define EVERGREEN_GRPH_RED_CROSSBAR(x) (((x) & 0x3) << 4) +# define EVERGREEN_GRPH_RED_SEL_R 0 +# define EVERGREEN_GRPH_RED_SEL_G 1 +# define EVERGREEN_GRPH_RED_SEL_B 2 +# define EVERGREEN_GRPH_RED_SEL_A 3 +# define EVERGREEN_GRPH_GREEN_CROSSBAR(x) (((x) & 0x3) << 6) +# define EVERGREEN_GRPH_GREEN_SEL_G 0 +# define EVERGREEN_GRPH_GREEN_SEL_B 1 +# define EVERGREEN_GRPH_GREEN_SEL_A 2 +# define EVERGREEN_GRPH_GREEN_SEL_R 3 +# define EVERGREEN_GRPH_BLUE_CROSSBAR(x) (((x) & 0x3) << 8) +# define EVERGREEN_GRPH_BLUE_SEL_B 0 +# define EVERGREEN_GRPH_BLUE_SEL_A 1 +# define EVERGREEN_GRPH_BLUE_SEL_R 2 +# define EVERGREEN_GRPH_BLUE_SEL_G 3 +# define EVERGREEN_GRPH_ALPHA_CROSSBAR(x) (((x) & 0x3) << 10) +# define EVERGREEN_GRPH_ALPHA_SEL_A 0 +# define EVERGREEN_GRPH_ALPHA_SEL_R 1 +# define EVERGREEN_GRPH_ALPHA_SEL_G 2 +# define EVERGREEN_GRPH_ALPHA_SEL_B 3 +#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS 0x6810 +#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS 0x6814 +# define EVERGREEN_GRPH_DFQ_ENABLE (1 << 0) +# define EVERGREEN_GRPH_SURFACE_ADDRESS_MASK 0xffffff00 +#define EVERGREEN_GRPH_PITCH 0x6818 +#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x681c +#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x6820 +#define EVERGREEN_GRPH_SURFACE_OFFSET_X 0x6824 +#define EVERGREEN_GRPH_SURFACE_OFFSET_Y 0x6828 +#define EVERGREEN_GRPH_X_START 0x682c +#define EVERGREEN_GRPH_Y_START 0x6830 +#define EVERGREEN_GRPH_X_END 0x6834 +#define EVERGREEN_GRPH_Y_END 0x6838 + +/* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ +#define EVERGREEN_CUR_CONTROL 0x6998 +# define EVERGREEN_CURSOR_EN (1 << 0) +# define EVERGREEN_CURSOR_MODE(x) (((x) & 0x3) << 8) +# define EVERGREEN_CURSOR_MONO 0 +# define EVERGREEN_CURSOR_24_1 1 +# define EVERGREEN_CURSOR_24_8_PRE_MULT 2 +# define EVERGREEN_CURSOR_24_8_UNPRE_MULT 3 +# define EVERGREEN_CURSOR_2X_MAGNIFY (1 << 16) +# define EVERGREEN_CURSOR_FORCE_MC_ON (1 << 20) +# define EVERGREEN_CURSOR_URGENT_CONTROL(x) (((x) & 0x7) << 24) +# define EVERGREEN_CURSOR_URGENT_ALWAYS 0 +# define EVERGREEN_CURSOR_URGENT_1_8 1 +# define EVERGREEN_CURSOR_URGENT_1_4 2 +# define EVERGREEN_CURSOR_URGENT_3_8 3 +# define EVERGREEN_CURSOR_URGENT_1_2 4 +#define EVERGREEN_CUR_SURFACE_ADDRESS 0x699c +# define EVERGREEN_CUR_SURFACE_ADDRESS_MASK 0xfffff000 +#define EVERGREEN_CUR_SIZE 0x69a0 +#define EVERGREEN_CUR_SURFACE_ADDRESS_HIGH 0x69a4 +#define EVERGREEN_CUR_POSITION 0x69a8 +#define EVERGREEN_CUR_HOT_SPOT 0x69ac +#define EVERGREEN_CUR_COLOR1 0x69b0 +#define EVERGREEN_CUR_COLOR2 0x69b4 +#define EVERGREEN_CUR_UPDATE 0x69b8 +# define EVERGREEN_CURSOR_UPDATE_PENDING (1 << 0) +# define EVERGREEN_CURSOR_UPDATE_TAKEN (1 << 1) +# define EVERGREEN_CURSOR_UPDATE_LOCK (1 << 16) +# define EVERGREEN_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24) + +/* LUT blocks at 0x69e0, 0x75e0, 0x101e0, 0x10de0, 0x119e0, 0x125e0 */ +#define EVERGREEN_DC_LUT_RW_MODE 0x69e0 +#define EVERGREEN_DC_LUT_RW_INDEX 0x69e4 +#define EVERGREEN_DC_LUT_SEQ_COLOR 0x69e8 +#define EVERGREEN_DC_LUT_PWL_DATA 0x69ec +#define EVERGREEN_DC_LUT_30_COLOR 0x69f0 +#define EVERGREEN_DC_LUT_VGA_ACCESS_ENABLE 0x69f4 +#define EVERGREEN_DC_LUT_WRITE_EN_MASK 0x69f8 +#define EVERGREEN_DC_LUT_AUTOFILL 0x69fc +#define EVERGREEN_DC_LUT_CONTROL 0x6a00 +#define EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE 0x6a04 +#define EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN 0x6a08 +#define EVERGREEN_DC_LUT_BLACK_OFFSET_RED 0x6a0c +#define EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE 0x6a10 +#define EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN 0x6a14 +#define EVERGREEN_DC_LUT_WHITE_OFFSET_RED 0x6a18 + +#define EVERGREEN_DATA_FORMAT 0x6b00 +# define EVERGREEN_INTERLEAVE_EN (1 << 0) +#define EVERGREEN_DESKTOP_HEIGHT 0x6b04 + +#define EVERGREEN_VIEWPORT_START 0x6d70 +#define EVERGREEN_VIEWPORT_SIZE 0x6d74 + +/* display controller offsets used for crtc/cur/lut/grph/viewport/etc. */ +#define EVERGREEN_CRTC0_REGISTER_OFFSET (0x6df0 - 0x6df0) +#define EVERGREEN_CRTC1_REGISTER_OFFSET (0x79f0 - 0x6df0) +#define EVERGREEN_CRTC2_REGISTER_OFFSET (0x105f0 - 0x6df0) +#define EVERGREEN_CRTC3_REGISTER_OFFSET (0x111f0 - 0x6df0) +#define EVERGREEN_CRTC4_REGISTER_OFFSET (0x11df0 - 0x6df0) +#define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) + +/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ +#define EVERGREEN_CRTC_CONTROL 0x6e70 +# define EVERGREEN_CRTC_MASTER_EN (1 << 0) +#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 + +#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 +#define EVERGREEN_DC_GPIO_HPD_A 0x64b4 +#define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 +#define EVERGREEN_DC_GPIO_HPD_Y 0x64bc + +#endif diff --git a/drivers/video/drm/radeon/makefile b/drivers/video/drm/radeon/makefile index 783f625378..dfe5d02594 100644 --- a/drivers/video/drm/radeon/makefile +++ b/drivers/video/drm/radeon/makefile @@ -1,4 +1,5 @@ + CC = gcc FASM = e:/fasm/fasm.exe @@ -48,6 +49,7 @@ NAME_SRC= \ $(DRM_TOPDIR)/drm_dp_i2c_helper.c \ $(DRM_TOPDIR)/i2c/i2c-core.c \ $(DRM_TOPDIR)/i2c/i2c-algo-bit.c \ + evergreen.c \ radeon_device.c \ radeon_clocks.c \ radeon_i2c.c \ diff --git a/drivers/video/drm/radeon/r100.c b/drivers/video/drm/radeon/r100.c index cdebb2b85f..e05296f195 100644 --- a/drivers/video/drm/radeon/r100.c +++ b/drivers/video/drm/radeon/r100.c @@ -195,13 +195,13 @@ int r100_pci_gart_enable(struct radeon_device *rdev) { uint32_t tmp; + radeon_gart_restore(rdev); /* discard memory request outside of configured range */ tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; WREG32(RADEON_AIC_CNTL, tmp); /* set address range for PCI address translate */ - WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location); - tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; - WREG32(RADEON_AIC_HI_ADDR, tmp); + WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start); + WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end); /* set PCI GART page-table base address */ WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; @@ -284,8 +284,8 @@ void r100_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL); /* Wait until IDLE & CLEAN */ - radeon_ring_write(rdev, PACKET0(0x1720, 0)); - radeon_ring_write(rdev, (1 << 16) | (1 << 17)); + radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); radeon_ring_write(rdev, rdev->config.r100.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); @@ -479,7 +479,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev) const char *fw_name = NULL; int err; - DRM_DEBUG("\n"); + DRM_DEBUG("\n"); pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); err = IS_ERR(pdev); @@ -710,8 +710,6 @@ int r100_cp_reset(struct radeon_device *rdev) bool reinit_cp; int i; - ENTER(); - reinit_cp = rdev->cp.ready; rdev->cp.ready = false; WREG32(RADEON_CP_CSQ_MODE, 0); @@ -1630,7 +1628,7 @@ int r100_gui_wait_for_idle(struct radeon_device *rdev) } for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(RADEON_RBBM_STATUS); - if (!(tmp & (1 << 31))) { + if (!(tmp & RADEON_RBBM_ACTIVE)) { return 0; } DRM_UDELAY(1); @@ -1645,8 +1643,8 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) for (i = 0; i < rdev->usec_timeout; i++) { /* read MC_STATUS */ - tmp = RREG32(0x0150); - if (tmp & (1 << 2)) { + tmp = RREG32(RADEON_MC_STATUS); + if (tmp & RADEON_MC_IDLE) { return 0; } DRM_UDELAY(1); @@ -1664,8 +1662,6 @@ void r100_hdp_reset(struct radeon_device *rdev) { uint32_t tmp; - ENTER(); - tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; tmp |= (7 << 28); WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE); @@ -1681,8 +1677,6 @@ int r100_rb2d_reset(struct radeon_device *rdev) uint32_t tmp; int i; - ENTER(); - WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2); (void)RREG32(RADEON_RBBM_SOFT_RESET); udelay(200); @@ -1723,7 +1717,7 @@ int r100_gpu_reset(struct radeon_device *rdev) } /* Check if GPU is idle */ status = RREG32(RADEON_RBBM_STATUS); - if (status & (1 << 31)) { + if (status & RADEON_RBBM_ACTIVE) { DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); return -1; } @@ -1733,6 +1727,9 @@ int r100_gpu_reset(struct radeon_device *rdev) void r100_set_common_regs(struct radeon_device *rdev) { + struct drm_device *dev = rdev->ddev; + bool force_dac2 = false; + /* set these so they don't interfere with anything */ WREG32(RADEON_OV0_SCALE_CNTL, 0); WREG32(RADEON_SUBPIC_CNTL, 0); @@ -1741,6 +1738,68 @@ void r100_set_common_regs(struct radeon_device *rdev) WREG32(RADEON_DVI_I2C_CNTL_1, 0); WREG32(RADEON_CAP0_TRIG_CNTL, 0); WREG32(RADEON_CAP1_TRIG_CNTL, 0); + + /* always set up dac2 on rn50 and some rv100 as lots + * of servers seem to wire it up to a VGA port but + * don't report it in the bios connector + * table. + */ + switch (dev->pdev->device) { + /* RN50 */ + case 0x515e: + case 0x5969: + force_dac2 = true; + break; + /* RV100*/ + case 0x5159: + case 0x515a: + /* DELL triple head servers */ + if ((dev->pdev->subsystem_vendor == 0x1028 /* DELL */) && + ((dev->pdev->subsystem_device == 0x016c) || + (dev->pdev->subsystem_device == 0x016d) || + (dev->pdev->subsystem_device == 0x016e) || + (dev->pdev->subsystem_device == 0x016f) || + (dev->pdev->subsystem_device == 0x0170) || + (dev->pdev->subsystem_device == 0x017d) || + (dev->pdev->subsystem_device == 0x017e) || + (dev->pdev->subsystem_device == 0x0183) || + (dev->pdev->subsystem_device == 0x018a) || + (dev->pdev->subsystem_device == 0x019a))) + force_dac2 = true; + break; + } + + if (force_dac2) { + u32 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); + u32 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); + u32 dac2_cntl = RREG32(RADEON_DAC_CNTL2); + + /* For CRT on DAC2, don't turn it on if BIOS didn't + enable it, even it's detected. + */ + + /* force it to crtc0 */ + dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; + dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL; + disp_hw_debug |= RADEON_CRT2_DISP1_SEL; + + /* set up the TV DAC */ + tv_dac_cntl &= ~(RADEON_TV_DAC_PEDESTAL | + RADEON_TV_DAC_STD_MASK | + RADEON_TV_DAC_RDACPD | + RADEON_TV_DAC_GDACPD | + RADEON_TV_DAC_BDACPD | + RADEON_TV_DAC_BGADJ_MASK | + RADEON_TV_DAC_DACADJ_MASK); + tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | + RADEON_TV_DAC_NHOLD | + RADEON_TV_DAC_STD_PS2 | + (0x58 << 16)); + + WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); + WREG32(RADEON_DAC_CNTL2, dac2_cntl); + } } /* @@ -1822,17 +1881,20 @@ static u32 r100_get_accessible_vram(struct radeon_device *rdev) void r100_vram_init_sizes(struct radeon_device *rdev) { u64 config_aper_size; - u32 accessible; + /* work out accessible VRAM */ + rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); + rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); + /* FIXME we don't use the second aperture yet when we could use it */ + if (rdev->mc.visible_vram_size > rdev->mc.aper_size) + rdev->mc.visible_vram_size = rdev->mc.aper_size; config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); - if (rdev->flags & RADEON_IS_IGP) { uint32_t tom; /* read NB_TOM to get the amount of ram stolen for the GPU */ tom = RREG32(RADEON_NB_TOM); rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16); - /* for IGPs we need to keep VRAM where it was put by the BIOS */ - rdev->mc.vram_location = (tom & 0xffff) << 16; WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; } else { @@ -1844,30 +1906,19 @@ void r100_vram_init_sizes(struct radeon_device *rdev) rdev->mc.real_vram_size = 8192 * 1024; WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); } - /* let driver place VRAM */ - rdev->mc.vram_location = 0xFFFFFFFFUL; /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - - * Novell bug 204882 + along with lots of ubuntu ones */ + * Novell bug 204882 + along with lots of ubuntu ones + */ if (config_aper_size > rdev->mc.real_vram_size) rdev->mc.mc_vram_size = config_aper_size; else rdev->mc.mc_vram_size = rdev->mc.real_vram_size; } - - /* work out accessible VRAM */ - accessible = r100_get_accessible_vram(rdev); - - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); - - if (accessible > rdev->mc.aper_size) - accessible = rdev->mc.aper_size; - - if (rdev->mc.mc_vram_size > rdev->mc.aper_size) + /* FIXME remove this once we support unmappable VRAM */ + if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { rdev->mc.mc_vram_size = rdev->mc.aper_size; - - if (rdev->mc.real_vram_size > rdev->mc.aper_size) rdev->mc.real_vram_size = rdev->mc.aper_size; + } } void r100_vga_set_state(struct radeon_device *rdev, bool state) @@ -1884,11 +1935,18 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state) WREG32(RADEON_CONFIG_CNTL, temp); } -void r100_vram_info(struct radeon_device *rdev) +void r100_mc_init(struct radeon_device *rdev) { - r100_vram_get_type(rdev); + u64 base; + r100_vram_get_type(rdev); r100_vram_init_sizes(rdev); + base = rdev->mc.aper_base; + if (rdev->flags & RADEON_IS_IGP) + base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + radeon_vram_location(rdev, &rdev->mc, base); + if (!(rdev->flags & RADEON_IS_AGP)) + radeon_gtt_location(rdev, &rdev->mc); } @@ -2753,10 +2811,9 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save) { /* Update base address for crtc */ - WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location); + WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start); if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, - rdev->mc.vram_location); + WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start); } /* Restore CRTC registers */ WREG8(R_0003C2_GENMO_WT, save->GENMO_WT); @@ -2883,31 +2940,6 @@ static int r100_startup(struct radeon_device *rdev) } -int r100_mc_init(struct radeon_device *rdev) -{ - int r; - u32 tmp; - - /* Setup GPU memory space */ - rdev->mc.vram_location = 0xFFFFFFFFUL; - rdev->mc.gtt_location = 0xFFFFFFFFUL; - if (rdev->flags & RADEON_IS_IGP) { - tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM)); - rdev->mc.vram_location = tmp << 16; - } - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } else { - rdev->mc.gtt_location = rdev->mc.agp_base; - } - } - r = radeon_mc_setup(rdev); - if (r) - return r; - return 0; -} int r100_init(struct radeon_device *rdev) { @@ -2951,13 +2983,15 @@ int r100_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - r100_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = r100_mc_init(rdev); - dbgprintf("mc vram location %x\n", rdev->mc.vram_location); - if (r) - return r; + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); + if (r) { + radeon_agp_disable(rdev); + } + } + /* initialize VRAM */ + r100_mc_init(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); // if (r) diff --git a/drivers/video/drm/radeon/r200.c b/drivers/video/drm/radeon/r200.c index 4700cc500a..9b0f704a7e 100644 --- a/drivers/video/drm/radeon/r200.c +++ b/drivers/video/drm/radeon/r200.c @@ -31,6 +31,7 @@ #include "radeon_reg.h" #include "radeon.h" +#include "r100d.h" #include "r200_reg_safe.h" //#include "r100_track.h" diff --git a/drivers/video/drm/radeon/r300.c b/drivers/video/drm/radeon/r300.c index d28cac1d02..e9b10c6cad 100644 --- a/drivers/video/drm/radeon/r300.c +++ b/drivers/video/drm/radeon/r300.c @@ -117,18 +117,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) r = radeon_gart_table_vram_pin(rdev); if (r) return r; + radeon_gart_restore(rdev); /* discard memory request outside of configured range */ tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); - tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE; + WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_start); + tmp = rdev->mc.gtt_end & ~RADEON_GPU_PAGE_MASK; WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); table_addr = rdev->gart.table_addr; WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr); /* FIXME: setup default page */ - WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_location); + WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start); WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0); /* Clear error */ WREG32_PCIE(0x18, 0); @@ -174,18 +175,20 @@ void r300_fence_ring_emit(struct radeon_device *rdev, /* Who ever call radeon_fence_emit should call ring_lock and ask * for enough space (today caller are ib schedule and buffer move) */ /* Write SC register so SC & US assert idle */ - radeon_ring_write(rdev, PACKET0(0x43E0, 0)); + radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_TL, 0)); radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(0x43E4, 0)); + radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_BR, 0)); radeon_ring_write(rdev, 0); /* Flush 3D cache */ - radeon_ring_write(rdev, PACKET0(0x4E4C, 0)); - radeon_ring_write(rdev, (2 << 0)); - radeon_ring_write(rdev, PACKET0(0x4F18, 0)); - radeon_ring_write(rdev, (1 << 0)); + radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(rdev, R300_RB3D_DC_FLUSH); + radeon_ring_write(rdev, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(rdev, R300_ZC_FLUSH); /* Wait until IDLE & CLEAN */ - radeon_ring_write(rdev, PACKET0(0x1720, 0)); - radeon_ring_write(rdev, (1 << 17) | (1 << 16) | (1 << 9)); + radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(rdev, (RADEON_WAIT_3D_IDLECLEAN | + RADEON_WAIT_2D_IDLECLEAN | + RADEON_WAIT_DMA_GUI_IDLE)); radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); radeon_ring_write(rdev, rdev->config.r300.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); @@ -198,56 +201,6 @@ void r300_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(rdev, RADEON_SW_INT_FIRE); } - -#if 0 - - -int r300_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_pages, - struct radeon_fence *fence) -{ - uint32_t size; - uint32_t cur_size; - int i, num_loops; - int r = 0; - - /* radeon pitch is /64 */ - size = num_pages << PAGE_SHIFT; - num_loops = DIV_ROUND_UP(size, 0x1FFFFF); - r = radeon_ring_lock(rdev, num_loops * 4 + 64); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return r; - } - /* Must wait for 2D idle & clean before DMA or hangs might happen */ - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0 )); - radeon_ring_write(rdev, (1 << 16)); - for (i = 0; i < num_loops; i++) { - cur_size = size; - if (cur_size > 0x1FFFFF) { - cur_size = 0x1FFFFF; - } - size -= cur_size; - radeon_ring_write(rdev, PACKET0(0x720, 2)); - radeon_ring_write(rdev, src_offset); - radeon_ring_write(rdev, dst_offset); - radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30)); - src_offset += cur_size; - dst_offset += cur_size; - } - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE); - if (fence) { - r = radeon_fence_emit(rdev, fence); - } - radeon_ring_unlock_commit(rdev); - return r; -} - -#endif - void r300_ring_start(struct radeon_device *rdev) { unsigned gb_tile_config; @@ -287,8 +240,8 @@ void r300_ring_start(struct radeon_device *rdev) radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(0x170C, 0)); - radeon_ring_write(rdev, 1 << 31); + radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0)); + radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG); radeon_ring_write(rdev, PACKET0(R300_GB_SELECT, 0)); radeon_ring_write(rdev, 0); radeon_ring_write(rdev, PACKET0(R300_GB_ENABLE, 0)); @@ -355,8 +308,8 @@ int r300_mc_wait_for_idle(struct radeon_device *rdev) for (i = 0; i < rdev->usec_timeout; i++) { /* read MC_STATUS */ - tmp = RREG32(0x0150); - if (tmp & (1 << 4)) { + tmp = RREG32(RADEON_MC_STATUS); + if (tmp & R300_MC_IDLE) { return 0; } DRM_UDELAY(1); @@ -401,8 +354,8 @@ void r300_gpu_init(struct radeon_device *rdev) "programming pipes. Bad things might happen.\n"); } - tmp = RREG32(0x170C); - WREG32(0x170C, tmp | (1 << 31)); + tmp = RREG32(R300_DST_PIPE_CONFIG); + WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG); WREG32(R300_RB2D_DSTCACHE_MODE, R300_DC_AUTOFLUSH_ENABLE | @@ -443,8 +396,8 @@ int r300_ga_reset(struct radeon_device *rdev) /* GA still busy soft reset it */ WREG32(0x429C, 0x200); WREG32(R300_VAP_PVS_STATE_FLUSH_REG, 0); - WREG32(0x43E0, 0); - WREG32(0x43E4, 0); + WREG32(R300_RE_SCISSORS_TL, 0); + WREG32(R300_RE_SCISSORS_BR, 0); WREG32(0x24AC, 0); } /* Wait to prevent race in RBBM_STATUS */ @@ -494,7 +447,7 @@ int r300_gpu_reset(struct radeon_device *rdev) } /* Check if GPU is idle */ status = RREG32(RADEON_RBBM_STATUS); - if (status & (1 << 31)) { + if (status & RADEON_RBBM_ACTIVE) { DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); return -1; } @@ -506,13 +459,13 @@ int r300_gpu_reset(struct radeon_device *rdev) /* * r300,r350,rv350,rv380 VRAM info */ -void r300_vram_info(struct radeon_device *rdev) +void r300_mc_init(struct radeon_device *rdev) { - uint32_t tmp; + u64 base; + u32 tmp; /* DDR for all card after R300 & IGP */ rdev->mc.vram_is_ddr = true; - tmp = RREG32(RADEON_MEM_CNTL); tmp &= R300_MEM_NUM_CHANNELS_MASK; switch (tmp) { @@ -521,8 +474,13 @@ void r300_vram_info(struct radeon_device *rdev) case 2: rdev->mc.vram_width = 256; break; default: rdev->mc.vram_width = 128; break; } - r100_vram_init_sizes(rdev); + base = rdev->mc.aper_base; + if (rdev->flags & RADEON_IS_IGP) + base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + radeon_vram_location(rdev, &rdev->mc, base); + if (!(rdev->flags & RADEON_IS_AGP)) + radeon_gtt_location(rdev, &rdev->mc); } void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) @@ -584,6 +542,40 @@ void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) } +int rv370_get_pcie_lanes(struct radeon_device *rdev) +{ + u32 link_width_cntl; + + if (rdev->flags & RADEON_IS_IGP) + return 0; + + if (!(rdev->flags & RADEON_IS_PCIE)) + return 0; + + /* FIXME wait for idle */ + + if (rdev->family < CHIP_R600) + link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); + else + link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); + + switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { + case RADEON_PCIE_LC_LINK_WIDTH_X0: + return 0; + case RADEON_PCIE_LC_LINK_WIDTH_X1: + return 1; + case RADEON_PCIE_LC_LINK_WIDTH_X2: + return 2; + case RADEON_PCIE_LC_LINK_WIDTH_X4: + return 4; + case RADEON_PCIE_LC_LINK_WIDTH_X8: + return 8; + case RADEON_PCIE_LC_LINK_WIDTH_X16: + default: + return 16; + } +} + #if defined(CONFIG_DEBUG_FS) static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data) { @@ -716,6 +708,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, tile_flags |= R300_TXO_MACRO_TILE; if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) tile_flags |= R300_TXO_MICRO_TILE; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_TXO_MICRO_TILE_SQUARE; tmp = idx_value + ((u32)reloc->lobj.gpu_offset); tmp |= tile_flags; @@ -766,6 +760,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, tile_flags |= R300_COLOR_TILE_ENABLE; if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) tile_flags |= R300_COLOR_MICROTILE_ENABLE; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; tmp = idx_value & ~(0x7 << 16); tmp |= tile_flags; @@ -837,7 +833,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) tile_flags |= R300_DEPTHMACROTILE_ENABLE; if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_DEPTHMICROTILE_TILED;; + tile_flags |= R300_DEPTHMICROTILE_TILED; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; tmp = idx_value & ~(0x7 << 16); tmp |= tile_flags; @@ -1347,13 +1345,15 @@ int r300_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - r300_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = r420_mc_init(rdev); - dbgprintf("mc vram location %x\n", rdev->mc.vram_location); - if (r) - return r; + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); + if (r) { + radeon_agp_disable(rdev); + } + } + /* initialize memory controller */ + r300_mc_init(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); // if (r) diff --git a/drivers/video/drm/radeon/r300_reg.h b/drivers/video/drm/radeon/r300_reg.h index a4eef703ea..b6da6fe3b8 100644 --- a/drivers/video/drm/radeon/r300_reg.h +++ b/drivers/video/drm/radeon/r300_reg.h @@ -952,6 +952,7 @@ # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) # define R300_TXO_MACRO_TILE (1 << 2) # define R300_TXO_MICRO_TILE (1 << 3) +# define R300_TXO_MICRO_TILE_SQUARE (2 << 3) # define R300_TXO_OFFSET_MASK 0xffffffe0 # define R300_TXO_OFFSET_SHIFT 5 /* END: Guess from R200 */ @@ -1360,6 +1361,7 @@ # define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ # define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ +# define R300_COLOR_MICROTILE_SQUARE_ENABLE (2 << 17) # define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ # define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ # define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ diff --git a/drivers/video/drm/radeon/r420.c b/drivers/video/drm/radeon/r420.c index 6c7bc979c2..0654434bd4 100644 --- a/drivers/video/drm/radeon/r420.c +++ b/drivers/video/drm/radeon/r420.c @@ -40,28 +40,6 @@ static void r420_set_reg_safe(struct radeon_device *rdev) rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm); } -int r420_mc_init(struct radeon_device *rdev) -{ - int r; - - /* Setup GPU memory space */ - rdev->mc.vram_location = 0xFFFFFFFFUL; - rdev->mc.gtt_location = 0xFFFFFFFFUL; - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } else { - rdev->mc.gtt_location = rdev->mc.agp_base; - } - } - r = radeon_mc_setup(rdev); - if (r) { - return r; - } - return 0; -} - void r420_pipes_init(struct radeon_device *rdev) { unsigned tmp; @@ -69,7 +47,8 @@ void r420_pipes_init(struct radeon_device *rdev) unsigned num_pipes; /* GA_ENHANCE workaround TCL deadlock issue */ - WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); + WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL | + (1 << 2) | (1 << 3)); /* add idle wait as per freedesktop.org bug 24041 */ if (r100_gui_wait_for_idle(rdev)) { printk(KERN_WARNING "Failed to wait GUI idle while " @@ -97,17 +76,17 @@ void r420_pipes_init(struct radeon_device *rdev) tmp = (7 << 1); break; } - WREG32(0x42C8, (1 << num_pipes) - 1); + WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1); /* Sub pixel 1/12 so we can have 4K rendering according to doc */ - tmp |= (1 << 4) | (1 << 0); - WREG32(0x4018, tmp); + tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING; + WREG32(R300_GB_TILE_CONFIG, tmp); if (r100_gui_wait_for_idle(rdev)) { printk(KERN_WARNING "Failed to wait GUI idle while " "programming pipes. Bad things might happen.\n"); } - tmp = RREG32(0x170C); - WREG32(0x170C, tmp | (1 << 31)); + tmp = RREG32(R300_DST_PIPE_CONFIG); + WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG); WREG32(R300_RB2D_DSTCACHE_MODE, RREG32(R300_RB2D_DSTCACHE_MODE) | @@ -314,13 +293,15 @@ int r420_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - r300_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = r420_mc_init(rdev); + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); if (r) { - return r; + radeon_agp_disable(rdev); } + } + /* initialize memory controller */ + r300_mc_init(rdev); r420_debugfs(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); diff --git a/drivers/video/drm/radeon/r500_reg.h b/drivers/video/drm/radeon/r500_reg.h index 27a3a8c478..82644315b9 100644 --- a/drivers/video/drm/radeon/r500_reg.h +++ b/drivers/video/drm/radeon/r500_reg.h @@ -717,54 +717,62 @@ #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 #define AVIVO_DC_GPIO_HPD_A 0x7e94 - -#define AVIVO_GPIO_0 0x7e30 -#define AVIVO_GPIO_1 0x7e40 -#define AVIVO_GPIO_2 0x7e50 -#define AVIVO_GPIO_3 0x7e60 - #define AVIVO_DC_GPIO_HPD_Y 0x7e9c -#define AVIVO_I2C_STATUS 0x7d30 -# define AVIVO_I2C_STATUS_DONE (1 << 0) -# define AVIVO_I2C_STATUS_NACK (1 << 1) -# define AVIVO_I2C_STATUS_HALT (1 << 2) -# define AVIVO_I2C_STATUS_GO (1 << 3) -# define AVIVO_I2C_STATUS_MASK 0x7 -/* If radeon_mm_i2c is to be believed, this is HALT, NACK, and maybe - * DONE? */ -# define AVIVO_I2C_STATUS_CMD_RESET 0x7 -# define AVIVO_I2C_STATUS_CMD_WAIT (1 << 3) -#define AVIVO_I2C_STOP 0x7d34 -#define AVIVO_I2C_START_CNTL 0x7d38 -# define AVIVO_I2C_START (1 << 8) -# define AVIVO_I2C_CONNECTOR0 (0 << 16) -# define AVIVO_I2C_CONNECTOR1 (1 << 16) -#define R520_I2C_START (1<<0) -#define R520_I2C_STOP (1<<1) -#define R520_I2C_RX (1<<2) -#define R520_I2C_EN (1<<8) -#define R520_I2C_DDC1 (0<<16) -#define R520_I2C_DDC2 (1<<16) -#define R520_I2C_DDC3 (2<<16) -#define R520_I2C_DDC_MASK (3<<16) -#define AVIVO_I2C_CONTROL2 0x7d3c -# define AVIVO_I2C_7D3C_SIZE_SHIFT 8 -# define AVIVO_I2C_7D3C_SIZE_MASK (0xf << 8) -#define AVIVO_I2C_CONTROL3 0x7d40 -/* Reading is done 4 bytes at a time: read the bottom 8 bits from - * 7d44, four times in a row. - * Writing is a little more complex. First write DATA with - * 0xnnnnnnzz, then 0xnnnnnnyy, where nnnnnn is some non-deterministic - * magic number, zz is, I think, the slave address, and yy is the byte - * you want to write. */ -#define AVIVO_I2C_DATA 0x7d44 -#define R520_I2C_ADDR_COUNT_MASK (0x7) -#define R520_I2C_DATA_COUNT_SHIFT (8) -#define R520_I2C_DATA_COUNT_MASK (0xF00) -#define AVIVO_I2C_CNTL 0x7d50 -# define AVIVO_I2C_EN (1 << 0) -# define AVIVO_I2C_RESET (1 << 8) +#define AVIVO_DC_I2C_STATUS1 0x7d30 +# define AVIVO_DC_I2C_DONE (1 << 0) +# define AVIVO_DC_I2C_NACK (1 << 1) +# define AVIVO_DC_I2C_HALT (1 << 2) +# define AVIVO_DC_I2C_GO (1 << 3) +#define AVIVO_DC_I2C_RESET 0x7d34 +# define AVIVO_DC_I2C_SOFT_RESET (1 << 0) +# define AVIVO_DC_I2C_ABORT (1 << 8) +#define AVIVO_DC_I2C_CONTROL1 0x7d38 +# define AVIVO_DC_I2C_START (1 << 0) +# define AVIVO_DC_I2C_STOP (1 << 1) +# define AVIVO_DC_I2C_RECEIVE (1 << 2) +# define AVIVO_DC_I2C_EN (1 << 8) +# define AVIVO_DC_I2C_PIN_SELECT(x) ((x) << 16) +# define AVIVO_SEL_DDC1 0 +# define AVIVO_SEL_DDC2 1 +# define AVIVO_SEL_DDC3 2 +#define AVIVO_DC_I2C_CONTROL2 0x7d3c +# define AVIVO_DC_I2C_ADDR_COUNT(x) ((x) << 0) +# define AVIVO_DC_I2C_DATA_COUNT(x) ((x) << 8) +#define AVIVO_DC_I2C_CONTROL3 0x7d40 +# define AVIVO_DC_I2C_DATA_DRIVE_EN (1 << 0) +# define AVIVO_DC_I2C_DATA_DRIVE_SEL (1 << 1) +# define AVIVO_DC_I2C_CLK_DRIVE_EN (1 << 7) +# define AVIVO_DC_I2C_RD_INTRA_BYTE_DELAY(x) ((x) << 8) +# define AVIVO_DC_I2C_WR_INTRA_BYTE_DELAY(x) ((x) << 16) +# define AVIVO_DC_I2C_TIME_LIMIT(x) ((x) << 24) +#define AVIVO_DC_I2C_DATA 0x7d44 +#define AVIVO_DC_I2C_INTERRUPT_CONTROL 0x7d48 +# define AVIVO_DC_I2C_INTERRUPT_STATUS (1 << 0) +# define AVIVO_DC_I2C_INTERRUPT_AK (1 << 8) +# define AVIVO_DC_I2C_INTERRUPT_ENABLE (1 << 16) +#define AVIVO_DC_I2C_ARBITRATION 0x7d50 +# define AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C (1 << 0) +# define AVIVO_DC_I2C_SW_CAN_USE_I2C (1 << 1) +# define AVIVO_DC_I2C_SW_DONE_USING_I2C (1 << 8) +# define AVIVO_DC_I2C_HW_NEEDS_I2C (1 << 9) +# define AVIVO_DC_I2C_ABORT_HDCP_I2C (1 << 16) +# define AVIVO_DC_I2C_HW_USING_I2C (1 << 17) + +#define AVIVO_DC_GPIO_DDC1_MASK 0x7e40 +#define AVIVO_DC_GPIO_DDC1_A 0x7e44 +#define AVIVO_DC_GPIO_DDC1_EN 0x7e48 +#define AVIVO_DC_GPIO_DDC1_Y 0x7e4c + +#define AVIVO_DC_GPIO_DDC2_MASK 0x7e50 +#define AVIVO_DC_GPIO_DDC2_A 0x7e54 +#define AVIVO_DC_GPIO_DDC2_EN 0x7e58 +#define AVIVO_DC_GPIO_DDC2_Y 0x7e5c + +#define AVIVO_DC_GPIO_DDC3_MASK 0x7e60 +#define AVIVO_DC_GPIO_DDC3_A 0x7e64 +#define AVIVO_DC_GPIO_DDC3_EN 0x7e68 +#define AVIVO_DC_GPIO_DDC3_Y 0x7e6c #define AVIVO_DISP_INTERRUPT_STATUS 0x7edc # define AVIVO_D1_VBLANK_INTERRUPT (1 << 4) diff --git a/drivers/video/drm/radeon/r520.c b/drivers/video/drm/radeon/r520.c index 58c8cc1c1d..ebdb2ccd37 100644 --- a/drivers/video/drm/radeon/r520.c +++ b/drivers/video/drm/radeon/r520.c @@ -51,7 +51,6 @@ static int r520_mc_wait_for_idle(struct radeon_device *rdev) static void r520_gpu_init(struct radeon_device *rdev) { unsigned pipe_select_current, gb_pipe_select, tmp; - ENTER(); r100_hdp_reset(rdev); rv515_vga_render_disable(rdev); @@ -95,7 +94,6 @@ static void r520_gpu_init(struct radeon_device *rdev) static void r520_vram_get_type(struct radeon_device *rdev) { uint32_t tmp; - ENTER(); rdev->mc.vram_width = 128; rdev->mc.vram_is_ddr = true; @@ -121,13 +119,15 @@ static void r520_vram_get_type(struct radeon_device *rdev) rdev->mc.vram_width *= 2; } -void r520_vram_info(struct radeon_device *rdev) +void r520_mc_init(struct radeon_device *rdev) { fixed20_12 a; r520_vram_get_type(rdev); - r100_vram_init_sizes(rdev); + radeon_vram_location(rdev, &rdev->mc, 0); + if (!(rdev->flags & RADEON_IS_AGP)) + radeon_gtt_location(rdev, &rdev->mc); /* FIXME: we should enforce default clock in case GPU is not in * default setup */ @@ -251,13 +251,15 @@ int r520_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - r520_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = r420_mc_init(rdev); - dbgprintf("mc vram location %x\n", rdev->mc.vram_location); - if (r) - return r; + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); + if (r) { + radeon_agp_disable(rdev); + } + } + /* initialize memory controller */ + r520_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); @@ -284,7 +286,6 @@ int r520_init(struct radeon_device *rdev) // r100_ib_fini(rdev); rv370_pcie_gart_fini(rdev); // radeon_agp_fini(rdev); -// radeon_irq_kms_fini(rdev); rdev->accel_working = false; } diff --git a/drivers/video/drm/radeon/r600.c b/drivers/video/drm/radeon/r600.c index eaa09fe5cf..8d7bd06c11 100644 --- a/drivers/video/drm/radeon/r600.c +++ b/drivers/video/drm/radeon/r600.c @@ -352,23 +352,14 @@ void r600_hpd_fini(struct radeon_device *rdev) /* * R600 PCIE GART */ -int r600_gart_clear_page(struct radeon_device *rdev, int i) -{ - void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; - u64 pte; - - if (i < 0 || i > rdev->gart.num_gpu_pages) - return -EINVAL; - pte = 0; - writeq(pte, ((void __iomem *)ptr) + (i * 8)); - return 0; -} - void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) { unsigned i; u32 tmp; + /* flush hdp cache so updates hit vram */ + WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); @@ -415,6 +406,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) r = radeon_gart_table_vram_pin(rdev); if (r) return r; + radeon_gart_restore(rdev); /* Setup L2 cache */ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | @@ -618,6 +610,68 @@ static void r600_mc_program(struct radeon_device *rdev) rv515_vga_render_disable(rdev); } +/** + * r600_vram_gtt_location - try to find VRAM & GTT location + * @rdev: radeon device structure holding all necessary informations + * @mc: memory controller structure holding memory informations + * + * Function will place try to place VRAM at same place as in CPU (PCI) + * address space as some GPU seems to have issue when we reprogram at + * different address space. + * + * If there is not enough space to fit the unvisible VRAM after the + * aperture then we limit the VRAM size to the aperture. + * + * If we are using AGP then place VRAM adjacent to AGP aperture are we need + * them to be in one from GPU point of view so that we can program GPU to + * catch access outside them (weird GPU policy see ??). + * + * This function will never fails, worst case are limiting VRAM or GTT. + * + * Note: GTT start, end, size should be initialized before calling this + * function on AGP platform. + */ +void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) +{ + u64 size_bf, size_af; + + if (mc->mc_vram_size > 0xE0000000) { + /* leave room for at least 512M GTT */ + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = 0xE0000000; + mc->mc_vram_size = 0xE0000000; + } + if (rdev->flags & RADEON_IS_AGP) { + size_bf = mc->gtt_start; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; + if (size_bf > size_af) { + if (mc->mc_vram_size > size_bf) { + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = size_bf; + mc->mc_vram_size = size_bf; + } + mc->vram_start = mc->gtt_start - mc->mc_vram_size; + } else { + if (mc->mc_vram_size > size_af) { + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = size_af; + mc->mc_vram_size = size_af; + } + mc->vram_start = mc->gtt_end; + } + mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; + dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", + mc->mc_vram_size >> 20, mc->vram_start, + mc->vram_end, mc->real_vram_size >> 20); + } else { + u64 base = 0; + if (rdev->flags & RADEON_IS_IGP) + base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; + radeon_vram_location(rdev, &rdev->mc, base); + radeon_gtt_location(rdev, mc); + } +} + int r600_mc_init(struct radeon_device *rdev) { fixed20_12 a; @@ -657,75 +711,21 @@ int r600_mc_init(struct radeon_device *rdev) /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); - - if (rdev->mc.mc_vram_size > rdev->mc.aper_size) + rdev->mc.visible_vram_size = rdev->mc.aper_size; + /* FIXME remove this once we support unmappable VRAM */ + if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { rdev->mc.mc_vram_size = rdev->mc.aper_size; - - if (rdev->mc.real_vram_size > rdev->mc.aper_size) rdev->mc.real_vram_size = rdev->mc.aper_size; - - if (rdev->flags & RADEON_IS_AGP) { - /* gtt_size is setup by radeon_agp_init */ - rdev->mc.gtt_location = rdev->mc.agp_base; - tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; - /* Try to put vram before or after AGP because we - * we want SYSTEM_APERTURE to cover both VRAM and - * AGP so that GPU can catch out of VRAM/AGP access - */ - if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { - /* Enough place before */ - rdev->mc.vram_location = rdev->mc.gtt_location - - rdev->mc.mc_vram_size; - } else if (tmp > rdev->mc.mc_vram_size) { - /* Enough place after */ - rdev->mc.vram_location = rdev->mc.gtt_location + - rdev->mc.gtt_size; - } else { - /* Try to setup VRAM then AGP might not - * not work on some card - */ - rdev->mc.vram_location = 0x00000000UL; - rdev->mc.gtt_location = rdev->mc.mc_vram_size; } - } else { - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; - rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & - 0xFFFF) << 24; - tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; - if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { - /* Enough place after vram */ - rdev->mc.gtt_location = tmp; - } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { - /* Enough place before vram */ - rdev->mc.gtt_location = 0; - } else { - /* Not enough place after or before shrink - * gart size - */ - if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { - rdev->mc.gtt_location = 0; - rdev->mc.gtt_size = rdev->mc.vram_location; - } else { - rdev->mc.gtt_location = tmp; - rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; - } - } - rdev->mc.gtt_location = rdev->mc.mc_vram_size; - } - rdev->mc.vram_start = rdev->mc.vram_location; - rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; - rdev->mc.gtt_start = rdev->mc.gtt_location; - rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; + r600_vram_gtt_location(rdev, &rdev->mc); /* FIXME: we should enforce default clock in case GPU is not in * default setup */ a.full = rfixed_const(100); rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); - if (rdev->flags & RADEON_IS_IGP) rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - return 0; } @@ -980,6 +980,9 @@ void r600_gpu_init(struct radeon_device *rdev) { u32 tiling_config; u32 ramcfg; + u32 backend_map; + u32 cc_rb_backend_disable; + u32 cc_gc_shader_pipe_config; u32 tmp; int i, j; u32 sq_config; @@ -1089,8 +1092,11 @@ void r600_gpu_init(struct radeon_device *rdev) default: break; } + rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; + rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= GROUP_SIZE(0); + rdev->config.r600.tiling_group_size = 256; tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; if (tmp > 3) { tiling_config |= ROW_TILING(3); @@ -1100,24 +1106,33 @@ void r600_gpu_init(struct radeon_device *rdev) tiling_config |= SAMPLE_SPLIT(tmp); } tiling_config |= BANK_SWAPS(1); - tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, - rdev->config.r600.max_backends, - (0xff << rdev->config.r600.max_backends) & 0xff); - tiling_config |= BACKEND_MAP(tmp); + + cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; + cc_rb_backend_disable |= + BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); + + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; + cc_gc_shader_pipe_config |= + INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); + cc_gc_shader_pipe_config |= + INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); + + backend_map = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, + (R6XX_MAX_BACKENDS - + r600_count_pipe_bits((cc_rb_backend_disable & + R6XX_MAX_BACKENDS_MASK) >> 16)), + (cc_rb_backend_disable >> 16)); + + tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, tiling_config); WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); - tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); - WREG32(CC_RB_BACKEND_DISABLE, tmp); - /* Setup pipes */ - tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); - tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); - WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp); - WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp); + WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); + WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK); + tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); @@ -1711,12 +1726,17 @@ void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ + + radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); + radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); + /* wait for 3D idle clean */ + radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); /* Emit fence sequence & fire IRQ */ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); radeon_ring_write(rdev, fence->seq); - radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); - radeon_ring_write(rdev, 1); /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); radeon_ring_write(rdev, RB_INT_STAT); @@ -1860,16 +1880,12 @@ int r600_init(struct radeon_device *rdev) /* Initialize power management */ radeon_pm_init(rdev); /* Fence driver */ -// r = radeon_fence_driver_init(rdev); -// if (r) -// return r; if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); if (r) radeon_agp_disable(rdev); } r = r600_mc_init(rdev); - dbgprintf("mc vram location %x\n", rdev->mc.vram_location); if (r) return r; /* Memory manager */ diff --git a/drivers/video/drm/radeon/r600_audio.c b/drivers/video/drm/radeon/r600_audio.c index 87a3491620..a8e5272265 100644 --- a/drivers/video/drm/radeon/r600_audio.c +++ b/drivers/video/drm/radeon/r600_audio.c @@ -35,7 +35,7 @@ */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && rdev->family < CHIP_RV710) + return rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; @@ -146,16 +146,24 @@ static void r600_audio_update_hdmi(unsigned long param) // jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); } +/* + * turn on/off audio engine + */ +static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) +{ + DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling"); + WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); +} + /* * initialize the audio vars and register the update timer */ int r600_audio_init(struct radeon_device *rdev) { - if (!r600_audio_chipset_supported(rdev)) + if (!radeon_audio || !r600_audio_chipset_supported(rdev)) return 0; - DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling"); - WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000); + r600_audio_engine_enable(rdev, true); rdev->audio_channels = -1; rdev->audio_rate = -1; @@ -258,10 +266,10 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) */ void r600_audio_fini(struct radeon_device *rdev) { - if (!r600_audio_chipset_supported(rdev)) + if (!radeon_audio || !r600_audio_chipset_supported(rdev)) return; - WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000); +// del_timer(&rdev->audio_timer); -// del_timer(&rdev->audio_timer); + r600_audio_engine_enable(rdev, false); } diff --git a/drivers/video/drm/radeon/r600d.h b/drivers/video/drm/radeon/r600d.h index 19e06a461f..1223ece762 100644 --- a/drivers/video/drm/radeon/r600d.h +++ b/drivers/video/drm/radeon/r600d.h @@ -883,6 +883,16 @@ #define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 +#define R_028C04_PA_SC_AA_CONFIG 0x028C04 +#define S_028C04_MSAA_NUM_SAMPLES(x) (((x) & 0x3) << 0) +#define G_028C04_MSAA_NUM_SAMPLES(x) (((x) >> 0) & 0x3) +#define C_028C04_MSAA_NUM_SAMPLES 0xFFFFFFFC +#define S_028C04_AA_MASK_CENTROID_DTMN(x) (((x) & 0x1) << 4) +#define G_028C04_AA_MASK_CENTROID_DTMN(x) (((x) >> 4) & 0x1) +#define C_028C04_AA_MASK_CENTROID_DTMN 0xFFFFFFEF +#define S_028C04_MAX_SAMPLE_DIST(x) (((x) & 0xF) << 13) +#define G_028C04_MAX_SAMPLE_DIST(x) (((x) >> 13) & 0xF) +#define C_028C04_MAX_SAMPLE_DIST 0xFFFE1FFF #define R_0280E0_CB_COLOR0_FRAG 0x0280E0 #define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) #define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) @@ -905,6 +915,461 @@ #define R_0280D4_CB_COLOR5_TILE 0x0280D4 #define R_0280D8_CB_COLOR6_TILE 0x0280D8 #define R_0280DC_CB_COLOR7_TILE 0x0280DC - +#define R_0280A0_CB_COLOR0_INFO 0x0280A0 +#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0) +#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3) +#define C_0280A0_ENDIAN 0xFFFFFFFC +#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2) +#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F) +#define C_0280A0_FORMAT 0xFFFFFF03 +#define V_0280A0_COLOR_INVALID 0x00000000 +#define V_0280A0_COLOR_8 0x00000001 +#define V_0280A0_COLOR_4_4 0x00000002 +#define V_0280A0_COLOR_3_3_2 0x00000003 +#define V_0280A0_COLOR_16 0x00000005 +#define V_0280A0_COLOR_16_FLOAT 0x00000006 +#define V_0280A0_COLOR_8_8 0x00000007 +#define V_0280A0_COLOR_5_6_5 0x00000008 +#define V_0280A0_COLOR_6_5_5 0x00000009 +#define V_0280A0_COLOR_1_5_5_5 0x0000000A +#define V_0280A0_COLOR_4_4_4_4 0x0000000B +#define V_0280A0_COLOR_5_5_5_1 0x0000000C +#define V_0280A0_COLOR_32 0x0000000D +#define V_0280A0_COLOR_32_FLOAT 0x0000000E +#define V_0280A0_COLOR_16_16 0x0000000F +#define V_0280A0_COLOR_16_16_FLOAT 0x00000010 +#define V_0280A0_COLOR_8_24 0x00000011 +#define V_0280A0_COLOR_8_24_FLOAT 0x00000012 +#define V_0280A0_COLOR_24_8 0x00000013 +#define V_0280A0_COLOR_24_8_FLOAT 0x00000014 +#define V_0280A0_COLOR_10_11_11 0x00000015 +#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016 +#define V_0280A0_COLOR_11_11_10 0x00000017 +#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018 +#define V_0280A0_COLOR_2_10_10_10 0x00000019 +#define V_0280A0_COLOR_8_8_8_8 0x0000001A +#define V_0280A0_COLOR_10_10_10_2 0x0000001B +#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C +#define V_0280A0_COLOR_32_32 0x0000001D +#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E +#define V_0280A0_COLOR_16_16_16_16 0x0000001F +#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020 +#define V_0280A0_COLOR_32_32_32_32 0x00000022 +#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023 +#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8) +#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF) +#define C_0280A0_ARRAY_MODE 0xFFFFF0FF +#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000 +#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001 +#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002 +#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004 +#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12) +#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7) +#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF +#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15) +#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1) +#define C_0280A0_READ_SIZE 0xFFFF7FFF +#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16) +#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3) +#define C_0280A0_COMP_SWAP 0xFFFCFFFF +#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) +#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) +#define C_0280A0_TILE_MODE 0xFFF3FFFF +#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) +#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) +#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF +#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21) +#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1) +#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF +#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22) +#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1) +#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF +#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23) +#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1) +#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF +#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24) +#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1) +#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF +#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25) +#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1) +#define C_0280A0_ROUND_MODE 0xFDFFFFFF +#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26) +#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1) +#define C_0280A0_TILE_COMPACT 0xFBFFFFFF +#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27) +#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1) +#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF +#define R_0280A4_CB_COLOR1_INFO 0x0280A4 +#define R_0280A8_CB_COLOR2_INFO 0x0280A8 +#define R_0280AC_CB_COLOR3_INFO 0x0280AC +#define R_0280B0_CB_COLOR4_INFO 0x0280B0 +#define R_0280B4_CB_COLOR5_INFO 0x0280B4 +#define R_0280B8_CB_COLOR6_INFO 0x0280B8 +#define R_0280BC_CB_COLOR7_INFO 0x0280BC +#define R_028060_CB_COLOR0_SIZE 0x028060 +#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) +#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) +#define C_028060_PITCH_TILE_MAX 0xFFFFFC00 +#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) +#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) +#define C_028060_SLICE_TILE_MAX 0xC00003FF +#define R_028064_CB_COLOR1_SIZE 0x028064 +#define R_028068_CB_COLOR2_SIZE 0x028068 +#define R_02806C_CB_COLOR3_SIZE 0x02806C +#define R_028070_CB_COLOR4_SIZE 0x028070 +#define R_028074_CB_COLOR5_SIZE 0x028074 +#define R_028078_CB_COLOR6_SIZE 0x028078 +#define R_02807C_CB_COLOR7_SIZE 0x02807C +#define R_028238_CB_TARGET_MASK 0x028238 +#define S_028238_TARGET0_ENABLE(x) (((x) & 0xF) << 0) +#define G_028238_TARGET0_ENABLE(x) (((x) >> 0) & 0xF) +#define C_028238_TARGET0_ENABLE 0xFFFFFFF0 +#define S_028238_TARGET1_ENABLE(x) (((x) & 0xF) << 4) +#define G_028238_TARGET1_ENABLE(x) (((x) >> 4) & 0xF) +#define C_028238_TARGET1_ENABLE 0xFFFFFF0F +#define S_028238_TARGET2_ENABLE(x) (((x) & 0xF) << 8) +#define G_028238_TARGET2_ENABLE(x) (((x) >> 8) & 0xF) +#define C_028238_TARGET2_ENABLE 0xFFFFF0FF +#define S_028238_TARGET3_ENABLE(x) (((x) & 0xF) << 12) +#define G_028238_TARGET3_ENABLE(x) (((x) >> 12) & 0xF) +#define C_028238_TARGET3_ENABLE 0xFFFF0FFF +#define S_028238_TARGET4_ENABLE(x) (((x) & 0xF) << 16) +#define G_028238_TARGET4_ENABLE(x) (((x) >> 16) & 0xF) +#define C_028238_TARGET4_ENABLE 0xFFF0FFFF +#define S_028238_TARGET5_ENABLE(x) (((x) & 0xF) << 20) +#define G_028238_TARGET5_ENABLE(x) (((x) >> 20) & 0xF) +#define C_028238_TARGET5_ENABLE 0xFF0FFFFF +#define S_028238_TARGET6_ENABLE(x) (((x) & 0xF) << 24) +#define G_028238_TARGET6_ENABLE(x) (((x) >> 24) & 0xF) +#define C_028238_TARGET6_ENABLE 0xF0FFFFFF +#define S_028238_TARGET7_ENABLE(x) (((x) & 0xF) << 28) +#define G_028238_TARGET7_ENABLE(x) (((x) >> 28) & 0xF) +#define C_028238_TARGET7_ENABLE 0x0FFFFFFF +#define R_02823C_CB_SHADER_MASK 0x02823C +#define S_02823C_OUTPUT0_ENABLE(x) (((x) & 0xF) << 0) +#define G_02823C_OUTPUT0_ENABLE(x) (((x) >> 0) & 0xF) +#define C_02823C_OUTPUT0_ENABLE 0xFFFFFFF0 +#define S_02823C_OUTPUT1_ENABLE(x) (((x) & 0xF) << 4) +#define G_02823C_OUTPUT1_ENABLE(x) (((x) >> 4) & 0xF) +#define C_02823C_OUTPUT1_ENABLE 0xFFFFFF0F +#define S_02823C_OUTPUT2_ENABLE(x) (((x) & 0xF) << 8) +#define G_02823C_OUTPUT2_ENABLE(x) (((x) >> 8) & 0xF) +#define C_02823C_OUTPUT2_ENABLE 0xFFFFF0FF +#define S_02823C_OUTPUT3_ENABLE(x) (((x) & 0xF) << 12) +#define G_02823C_OUTPUT3_ENABLE(x) (((x) >> 12) & 0xF) +#define C_02823C_OUTPUT3_ENABLE 0xFFFF0FFF +#define S_02823C_OUTPUT4_ENABLE(x) (((x) & 0xF) << 16) +#define G_02823C_OUTPUT4_ENABLE(x) (((x) >> 16) & 0xF) +#define C_02823C_OUTPUT4_ENABLE 0xFFF0FFFF +#define S_02823C_OUTPUT5_ENABLE(x) (((x) & 0xF) << 20) +#define G_02823C_OUTPUT5_ENABLE(x) (((x) >> 20) & 0xF) +#define C_02823C_OUTPUT5_ENABLE 0xFF0FFFFF +#define S_02823C_OUTPUT6_ENABLE(x) (((x) & 0xF) << 24) +#define G_02823C_OUTPUT6_ENABLE(x) (((x) >> 24) & 0xF) +#define C_02823C_OUTPUT6_ENABLE 0xF0FFFFFF +#define S_02823C_OUTPUT7_ENABLE(x) (((x) & 0xF) << 28) +#define G_02823C_OUTPUT7_ENABLE(x) (((x) >> 28) & 0xF) +#define C_02823C_OUTPUT7_ENABLE 0x0FFFFFFF +#define R_028AB0_VGT_STRMOUT_EN 0x028AB0 +#define S_028AB0_STREAMOUT(x) (((x) & 0x1) << 0) +#define G_028AB0_STREAMOUT(x) (((x) >> 0) & 0x1) +#define C_028AB0_STREAMOUT 0xFFFFFFFE +#define R_028B20_VGT_STRMOUT_BUFFER_EN 0x028B20 +#define S_028B20_BUFFER_0_EN(x) (((x) & 0x1) << 0) +#define G_028B20_BUFFER_0_EN(x) (((x) >> 0) & 0x1) +#define C_028B20_BUFFER_0_EN 0xFFFFFFFE +#define S_028B20_BUFFER_1_EN(x) (((x) & 0x1) << 1) +#define G_028B20_BUFFER_1_EN(x) (((x) >> 1) & 0x1) +#define C_028B20_BUFFER_1_EN 0xFFFFFFFD +#define S_028B20_BUFFER_2_EN(x) (((x) & 0x1) << 2) +#define G_028B20_BUFFER_2_EN(x) (((x) >> 2) & 0x1) +#define C_028B20_BUFFER_2_EN 0xFFFFFFFB +#define S_028B20_BUFFER_3_EN(x) (((x) & 0x1) << 3) +#define G_028B20_BUFFER_3_EN(x) (((x) >> 3) & 0x1) +#define C_028B20_BUFFER_3_EN 0xFFFFFFF7 +#define S_028B20_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028B20_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028B20_SIZE 0x00000000 +#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000 +#define S_038000_DIM(x) (((x) & 0x7) << 0) +#define G_038000_DIM(x) (((x) >> 0) & 0x7) +#define C_038000_DIM 0xFFFFFFF8 +#define V_038000_SQ_TEX_DIM_1D 0x00000000 +#define V_038000_SQ_TEX_DIM_2D 0x00000001 +#define V_038000_SQ_TEX_DIM_3D 0x00000002 +#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003 +#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004 +#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005 +#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006 +#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 +#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) +#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) +#define C_038000_TILE_MODE 0xFFFFFF87 +#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) +#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) +#define C_038000_TILE_TYPE 0xFFFFFF7F +#define S_038000_PITCH(x) (((x) & 0x7FF) << 8) +#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF) +#define C_038000_PITCH 0xFFF800FF +#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19) +#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF) +#define C_038000_TEX_WIDTH 0x0007FFFF +#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004 +#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0) +#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF) +#define C_038004_TEX_HEIGHT 0xFFFFE000 +#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13) +#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF) +#define C_038004_TEX_DEPTH 0xFC001FFF +#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26) +#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F) +#define C_038004_DATA_FORMAT 0x03FFFFFF +#define V_038004_COLOR_INVALID 0x00000000 +#define V_038004_COLOR_8 0x00000001 +#define V_038004_COLOR_4_4 0x00000002 +#define V_038004_COLOR_3_3_2 0x00000003 +#define V_038004_COLOR_16 0x00000005 +#define V_038004_COLOR_16_FLOAT 0x00000006 +#define V_038004_COLOR_8_8 0x00000007 +#define V_038004_COLOR_5_6_5 0x00000008 +#define V_038004_COLOR_6_5_5 0x00000009 +#define V_038004_COLOR_1_5_5_5 0x0000000A +#define V_038004_COLOR_4_4_4_4 0x0000000B +#define V_038004_COLOR_5_5_5_1 0x0000000C +#define V_038004_COLOR_32 0x0000000D +#define V_038004_COLOR_32_FLOAT 0x0000000E +#define V_038004_COLOR_16_16 0x0000000F +#define V_038004_COLOR_16_16_FLOAT 0x00000010 +#define V_038004_COLOR_8_24 0x00000011 +#define V_038004_COLOR_8_24_FLOAT 0x00000012 +#define V_038004_COLOR_24_8 0x00000013 +#define V_038004_COLOR_24_8_FLOAT 0x00000014 +#define V_038004_COLOR_10_11_11 0x00000015 +#define V_038004_COLOR_10_11_11_FLOAT 0x00000016 +#define V_038004_COLOR_11_11_10 0x00000017 +#define V_038004_COLOR_11_11_10_FLOAT 0x00000018 +#define V_038004_COLOR_2_10_10_10 0x00000019 +#define V_038004_COLOR_8_8_8_8 0x0000001A +#define V_038004_COLOR_10_10_10_2 0x0000001B +#define V_038004_COLOR_X24_8_32_FLOAT 0x0000001C +#define V_038004_COLOR_32_32 0x0000001D +#define V_038004_COLOR_32_32_FLOAT 0x0000001E +#define V_038004_COLOR_16_16_16_16 0x0000001F +#define V_038004_COLOR_16_16_16_16_FLOAT 0x00000020 +#define V_038004_COLOR_32_32_32_32 0x00000022 +#define V_038004_COLOR_32_32_32_32_FLOAT 0x00000023 +#define V_038004_FMT_1 0x00000025 +#define V_038004_FMT_GB_GR 0x00000027 +#define V_038004_FMT_BG_RG 0x00000028 +#define V_038004_FMT_32_AS_8 0x00000029 +#define V_038004_FMT_32_AS_8_8 0x0000002A +#define V_038004_FMT_5_9_9_9_SHAREDEXP 0x0000002B +#define V_038004_FMT_8_8_8 0x0000002C +#define V_038004_FMT_16_16_16 0x0000002D +#define V_038004_FMT_16_16_16_FLOAT 0x0000002E +#define V_038004_FMT_32_32_32 0x0000002F +#define V_038004_FMT_32_32_32_FLOAT 0x00000030 +#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 +#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) +#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) +#define C_038010_FORMAT_COMP_X 0xFFFFFFFC +#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) +#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) +#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3 +#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) +#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) +#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF +#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) +#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) +#define C_038010_FORMAT_COMP_W 0xFFFFFF3F +#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) +#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) +#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF +#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) +#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) +#define C_038010_SRF_MODE_ALL 0xFFFFFBFF +#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) +#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) +#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF +#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) +#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) +#define C_038010_ENDIAN_SWAP 0xFFFFCFFF +#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14) +#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3) +#define C_038010_REQUEST_SIZE 0xFFFF3FFF +#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16) +#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7) +#define C_038010_DST_SEL_X 0xFFF8FFFF +#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19) +#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7) +#define C_038010_DST_SEL_Y 0xFFC7FFFF +#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22) +#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7) +#define C_038010_DST_SEL_Z 0xFE3FFFFF +#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25) +#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7) +#define C_038010_DST_SEL_W 0xF1FFFFFF +#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28) +#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF) +#define C_038010_BASE_LEVEL 0x0FFFFFFF +#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014 +#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0) +#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF) +#define C_038014_LAST_LEVEL 0xFFFFFFF0 +#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) +#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) +#define C_038014_BASE_ARRAY 0xFFFE000F +#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) +#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) +#define C_038014_LAST_ARRAY 0xC001FFFF +#define R_0288A8_SQ_ESGS_RING_ITEMSIZE 0x0288A8 +#define S_0288A8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288A8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288A8_ITEMSIZE 0xFFFF8000 +#define R_008C44_SQ_ESGS_RING_SIZE 0x008C44 +#define S_008C44_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C44_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C44_MEM_SIZE 0x00000000 +#define R_0288B0_SQ_ESTMP_RING_ITEMSIZE 0x0288B0 +#define S_0288B0_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288B0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288B0_ITEMSIZE 0xFFFF8000 +#define R_008C54_SQ_ESTMP_RING_SIZE 0x008C54 +#define S_008C54_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C54_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C54_MEM_SIZE 0x00000000 +#define R_0288C0_SQ_FBUF_RING_ITEMSIZE 0x0288C0 +#define S_0288C0_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288C0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288C0_ITEMSIZE 0xFFFF8000 +#define R_008C74_SQ_FBUF_RING_SIZE 0x008C74 +#define S_008C74_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C74_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C74_MEM_SIZE 0x00000000 +#define R_0288B4_SQ_GSTMP_RING_ITEMSIZE 0x0288B4 +#define S_0288B4_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288B4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288B4_ITEMSIZE 0xFFFF8000 +#define R_008C5C_SQ_GSTMP_RING_SIZE 0x008C5C +#define S_008C5C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C5C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C5C_MEM_SIZE 0x00000000 +#define R_0288AC_SQ_GSVS_RING_ITEMSIZE 0x0288AC +#define S_0288AC_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288AC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288AC_ITEMSIZE 0xFFFF8000 +#define R_008C4C_SQ_GSVS_RING_SIZE 0x008C4C +#define S_008C4C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C4C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C4C_MEM_SIZE 0x00000000 +#define R_0288BC_SQ_PSTMP_RING_ITEMSIZE 0x0288BC +#define S_0288BC_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288BC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288BC_ITEMSIZE 0xFFFF8000 +#define R_008C6C_SQ_PSTMP_RING_SIZE 0x008C6C +#define S_008C6C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C6C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C6C_MEM_SIZE 0x00000000 +#define R_0288C4_SQ_REDUC_RING_ITEMSIZE 0x0288C4 +#define S_0288C4_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288C4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288C4_ITEMSIZE 0xFFFF8000 +#define R_008C7C_SQ_REDUC_RING_SIZE 0x008C7C +#define S_008C7C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C7C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C7C_MEM_SIZE 0x00000000 +#define R_0288B8_SQ_VSTMP_RING_ITEMSIZE 0x0288B8 +#define S_0288B8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288B8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288B8_ITEMSIZE 0xFFFF8000 +#define R_008C64_SQ_VSTMP_RING_SIZE 0x008C64 +#define S_008C64_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_008C64_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_008C64_MEM_SIZE 0x00000000 +#define R_0288C8_SQ_GS_VERT_ITEMSIZE 0x0288C8 +#define S_0288C8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) +#define G_0288C8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) +#define C_0288C8_ITEMSIZE 0xFFFF8000 +#define R_028010_DB_DEPTH_INFO 0x028010 +#define S_028010_FORMAT(x) (((x) & 0x7) << 0) +#define G_028010_FORMAT(x) (((x) >> 0) & 0x7) +#define C_028010_FORMAT 0xFFFFFFF8 +#define V_028010_DEPTH_INVALID 0x00000000 +#define V_028010_DEPTH_16 0x00000001 +#define V_028010_DEPTH_X8_24 0x00000002 +#define V_028010_DEPTH_8_24 0x00000003 +#define V_028010_DEPTH_X8_24_FLOAT 0x00000004 +#define V_028010_DEPTH_8_24_FLOAT 0x00000005 +#define V_028010_DEPTH_32_FLOAT 0x00000006 +#define V_028010_DEPTH_X24_8_32_FLOAT 0x00000007 +#define S_028010_READ_SIZE(x) (((x) & 0x1) << 3) +#define G_028010_READ_SIZE(x) (((x) >> 3) & 0x1) +#define C_028010_READ_SIZE 0xFFFFFFF7 +#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) +#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) +#define C_028010_ARRAY_MODE 0xFFF87FFF +#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) +#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) +#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF +#define S_028010_TILE_COMPACT(x) (((x) & 0x1) << 26) +#define G_028010_TILE_COMPACT(x) (((x) >> 26) & 0x1) +#define C_028010_TILE_COMPACT 0xFBFFFFFF +#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) +#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) +#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF +#define R_028000_DB_DEPTH_SIZE 0x028000 +#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) +#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) +#define C_028000_PITCH_TILE_MAX 0xFFFFFC00 +#define S_028000_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) +#define G_028000_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) +#define C_028000_SLICE_TILE_MAX 0xC00003FF +#define R_028004_DB_DEPTH_VIEW 0x028004 +#define S_028004_SLICE_START(x) (((x) & 0x7FF) << 0) +#define G_028004_SLICE_START(x) (((x) >> 0) & 0x7FF) +#define C_028004_SLICE_START 0xFFFFF800 +#define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13) +#define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF) +#define C_028004_SLICE_MAX 0xFF001FFF +#define R_028800_DB_DEPTH_CONTROL 0x028800 +#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) +#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) +#define C_028800_STENCIL_ENABLE 0xFFFFFFFE +#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1) +#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1) +#define C_028800_Z_ENABLE 0xFFFFFFFD +#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2) +#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1) +#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB +#define S_028800_ZFUNC(x) (((x) & 0x7) << 4) +#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7) +#define C_028800_ZFUNC 0xFFFFFF8F +#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7) +#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1) +#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F +#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) +#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) +#define C_028800_STENCILFUNC 0xFFFFF8FF +#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) +#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) +#define C_028800_STENCILFAIL 0xFFFFC7FF +#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) +#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) +#define C_028800_STENCILZPASS 0xFFFE3FFF +#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17) +#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7) +#define C_028800_STENCILZFAIL 0xFFF1FFFF +#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20) +#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7) +#define C_028800_STENCILFUNC_BF 0xFF8FFFFF +#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23) +#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7) +#define C_028800_STENCILFAIL_BF 0xFC7FFFFF +#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26) +#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7) +#define C_028800_STENCILZPASS_BF 0xE3FFFFFF +#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) +#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) +#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF #endif diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index 0e68affe2b..bfaf104d72 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -97,8 +97,13 @@ extern int radeon_testing; extern int radeon_connector_table; extern int radeon_tv; extern int radeon_new_pll; +extern int radeon_dynpm; extern int radeon_audio; +typedef struct pm_message { + int event; +} pm_message_t; + typedef struct { int width; @@ -181,6 +186,21 @@ struct radeon_device; /* * BIOS. */ +#define ATRM_BIOS_PAGE 4096 + +#if defined(CONFIG_VGA_SWITCHEROO) +bool radeon_atrm_supported(struct pci_dev *pdev); +int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); +#else +static inline bool radeon_atrm_supported(struct pci_dev *pdev) +{ + return false; +} + +static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ + return -EINVAL; +} +#endif bool radeon_get_bios(struct radeon_device *rdev); @@ -201,17 +221,23 @@ void radeon_dummy_page_fini(struct radeon_device *rdev); struct radeon_clock { struct radeon_pll p1pll; struct radeon_pll p2pll; + struct radeon_pll dcpll; struct radeon_pll spll; struct radeon_pll mpll; /* 10 Khz units */ uint32_t default_mclk; uint32_t default_sclk; + uint32_t default_dispclk; + uint32_t dp_extclk; }; /* * Power management */ int radeon_pm_init(struct radeon_device *rdev); +void radeon_pm_compute_clocks(struct radeon_device *rdev); +void radeon_combios_get_power_modes(struct radeon_device *rdev); +void radeon_atombios_get_power_modes(struct radeon_device *rdev); /* * Fences. @@ -339,6 +365,7 @@ union radeon_gart_table { }; #define RADEON_GPU_PAGE_SIZE 4096 +#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) struct radeon_gart { dma_addr_t table_addr; @@ -373,11 +400,10 @@ struct radeon_mc { /* for some chips with <= 32MB we need to lie * about vram size near mc fb location */ u64 mc_vram_size; - u64 gtt_location; + u64 visible_vram_size; u64 gtt_size; u64 gtt_start; u64 gtt_end; - u64 vram_location; u64 vram_start; u64 vram_end; unsigned vram_width; @@ -387,7 +413,6 @@ struct radeon_mc { bool igp_sideport_enabled; }; -int radeon_mc_setup(struct radeon_device *rdev); bool radeon_combios_sideport_present(struct radeon_device *rdev); bool radeon_atombios_sideport_present(struct radeon_device *rdev); @@ -443,6 +468,7 @@ struct radeon_ib { struct radeon_ib_pool { // struct mutex mutex; struct radeon_bo *robj; + struct list_head bogus_ib; struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; bool ready; unsigned head_id; @@ -496,6 +522,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); int radeon_ib_pool_init(struct radeon_device *rdev); void radeon_ib_pool_fini(struct radeon_device *rdev); int radeon_ib_test(struct radeon_device *rdev); +extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ void radeon_ring_free_size(struct radeon_device *rdev); int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw); @@ -529,6 +556,7 @@ struct radeon_cs_chunk { }; struct radeon_cs_parser { + struct device *dev; struct radeon_device *rdev; // struct drm_file *filp; /* chunks */ @@ -632,7 +660,99 @@ struct radeon_wb { * Equation between gpu/memory clock and available bandwidth is hw dependent * (type of memory, bus size, efficiency, ...) */ +enum radeon_pm_state { + PM_STATE_DISABLED, + PM_STATE_MINIMUM, + PM_STATE_PAUSED, + PM_STATE_ACTIVE +}; +enum radeon_pm_action { + PM_ACTION_NONE, + PM_ACTION_MINIMUM, + PM_ACTION_DOWNCLOCK, + PM_ACTION_UPCLOCK +}; + +enum radeon_voltage_type { + VOLTAGE_NONE = 0, + VOLTAGE_GPIO, + VOLTAGE_VDDC, + VOLTAGE_SW +}; + +enum radeon_pm_state_type { + POWER_STATE_TYPE_DEFAULT, + POWER_STATE_TYPE_POWERSAVE, + POWER_STATE_TYPE_BATTERY, + POWER_STATE_TYPE_BALANCED, + POWER_STATE_TYPE_PERFORMANCE, +}; + +enum radeon_pm_clock_mode_type { + POWER_MODE_TYPE_DEFAULT, + POWER_MODE_TYPE_LOW, + POWER_MODE_TYPE_MID, + POWER_MODE_TYPE_HIGH, +}; + +struct radeon_voltage { + enum radeon_voltage_type type; + /* gpio voltage */ + struct radeon_gpio_rec gpio; + u32 delay; /* delay in usec from voltage drop to sclk change */ + bool active_high; /* voltage drop is active when bit is high */ + /* VDDC voltage */ + u8 vddc_id; /* index into vddc voltage table */ + u8 vddci_id; /* index into vddci voltage table */ + bool vddci_enabled; + /* r6xx+ sw */ + u32 voltage; +}; + +struct radeon_pm_non_clock_info { + /* pcie lanes */ + int pcie_lanes; + /* standardized non-clock flags */ + u32 flags; +}; + +struct radeon_pm_clock_info { + /* memory clock */ + u32 mclk; + /* engine clock */ + u32 sclk; + /* voltage info */ + struct radeon_voltage voltage; + /* standardized clock flags - not sure we'll need these */ + u32 flags; +}; + +struct radeon_power_state { + enum radeon_pm_state_type type; + /* XXX: use a define for num clock modes */ + struct radeon_pm_clock_info clock_info[8]; + /* number of valid clock modes in this power state */ + int num_clock_modes; + struct radeon_pm_clock_info *default_clock_mode; + /* non clock info about this state */ + struct radeon_pm_non_clock_info non_clock_info; + bool voltage_drop_active; +}; + +/* + * Some modes are overclocked by very low value, accept them + */ +#define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */ + struct radeon_pm { +// struct mutex mutex; +// struct delayed_work idle_work; + enum radeon_pm_state state; + enum radeon_pm_action planned_action; + unsigned long action_timeout; + bool downclocked; + int active_crtcs; + int req_vblank; fixed20_12 max_bandwidth; fixed20_12 igp_sideport_mclk; fixed20_12 igp_system_mclk; @@ -644,6 +764,15 @@ struct radeon_pm { fixed20_12 core_bandwidth; fixed20_12 sclk; fixed20_12 needed_bandwidth; + /* XXX: use a define for num power modes */ + struct radeon_power_state power_state[8]; + /* number of valid power states */ + int num_power_states; + struct radeon_power_state *current_power_state; + struct radeon_pm_clock_info *current_clock_mode; + struct radeon_power_state *requested_power_state; + struct radeon_pm_clock_info *requested_clock_mode; + struct radeon_power_state *default_power_state; }; /* @@ -689,6 +818,7 @@ struct radeon_asic { void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); uint32_t (*get_memory_clock)(struct radeon_device *rdev); void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); + int (*get_pcie_lanes)(struct radeon_device *rdev); void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); void (*set_clock_gating)(struct radeon_device *rdev, int enable); int (*set_surface_reg)(struct radeon_device *rdev, int reg, @@ -739,6 +869,9 @@ struct r600_asic { unsigned sx_max_export_pos_size; unsigned sx_max_export_smx_size; unsigned sq_num_cf_insts; + unsigned tiling_nbanks; + unsigned tiling_npipes; + unsigned tiling_group_size; }; struct rv770_asic { @@ -759,6 +892,9 @@ struct rv770_asic { unsigned sc_prim_fifo_size; unsigned sc_hiz_tile_fifo_size; unsigned sc_earlyz_tile_fifo_fize; + unsigned tiling_nbanks; + unsigned tiling_npipes; + unsigned tiling_group_size; }; union radeon_asic_config { @@ -840,6 +976,7 @@ struct radeon_device { const struct firmware *rlc_fw; /* r6/700 RLC firmware */ struct r600_blit r600_blit; int msi_enabled; /* msi enabled */ + int num_crtc; /* number of crtcs */ /* audio stuff */ // struct timer_list audio_timer; @@ -848,6 +985,8 @@ struct radeon_device { int audio_bits_per_sample; uint8_t audio_status_bits; uint8_t audio_category_code; + + bool powered_down; }; int radeon_device_init(struct radeon_device *rdev, @@ -904,6 +1043,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) #define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg)) #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v)) +#define RREG32_PCIE_P(reg) rdev->pciep_rreg(rdev, (reg)) +#define WREG32_PCIE_P(reg, v) rdev->pciep_wreg(rdev, (reg), (v)) #define WREG32_P(reg, val, mask) \ do { \ uint32_t tmp_ = RREG32(reg); \ @@ -964,7 +1105,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) - +#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) /* * BIOS helpers. @@ -1023,6 +1164,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev)) #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e)) +#define radeon_get_pcie_lanes(rdev) (rdev)->asic->get_pcie_lanes((rdev)) #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) @@ -1037,6 +1179,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) /* AGP */ extern void radeon_agp_disable(struct radeon_device *rdev); extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); +extern void radeon_gart_restore(struct radeon_device *rdev); extern int radeon_modeset_init(struct radeon_device *rdev); extern void radeon_modeset_fini(struct radeon_device *rdev); extern bool radeon_card_posted(struct radeon_device *rdev); @@ -1050,6 +1193,10 @@ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enabl extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); +extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); +extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); +extern int radeon_resume_kms(struct drm_device *dev); +extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ struct r100_mc_save { @@ -1104,7 +1251,7 @@ extern void r200_set_safe_registers(struct radeon_device *rdev); /* r300,r350,rv350,rv370,rv380 */ extern void r300_set_reg_safe(struct radeon_device *rdev); extern void r300_mc_program(struct radeon_device *rdev); -extern void r300_vram_info(struct radeon_device *rdev); +extern void r300_mc_init(struct radeon_device *rdev); extern void r300_clock_startup(struct radeon_device *rdev); extern int r300_mc_wait_for_idle(struct radeon_device *rdev); extern int rv370_pcie_gart_init(struct radeon_device *rdev); @@ -1113,7 +1260,6 @@ extern int rv370_pcie_gart_enable(struct radeon_device *rdev); extern void rv370_pcie_gart_disable(struct radeon_device *rdev); /* r420,r423,rv410 */ -extern int r420_mc_init(struct radeon_device *rdev); extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); @@ -1155,13 +1301,13 @@ extern void rs690_line_buffer_adjust(struct radeon_device *rdev, struct drm_display_mode *mode2); /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ +extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern bool r600_card_posted(struct radeon_device *rdev); extern void r600_cp_stop(struct radeon_device *rdev); extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); extern int r600_cp_resume(struct radeon_device *rdev); extern void r600_cp_fini(struct radeon_device *rdev); extern int r600_count_pipe_bits(uint32_t val); -extern int r600_gart_clear_page(struct radeon_device *rdev, int i); extern int r600_mc_wait_for_idle(struct radeon_device *rdev); extern int r600_pcie_gart_init(struct radeon_device *rdev); extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); @@ -1197,6 +1343,14 @@ extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, uint8_t status_bits, uint8_t category_code); +/* evergreen */ +struct evergreen_mc_save { + u32 vga_control[6]; + u32 vga_render_control; + u32 vga_hdp_control; + u32 crtc_control[6]; +}; + #include "radeon_object.h" #define DRM_UDELAY(d) udelay(d) diff --git a/drivers/video/drm/radeon/radeon_agp.c b/drivers/video/drm/radeon/radeon_agp.c index 7f23f15b23..23457a704c 100644 --- a/drivers/video/drm/radeon/radeon_agp.c +++ b/drivers/video/drm/radeon/radeon_agp.c @@ -237,6 +237,10 @@ int radeon_agp_init(struct radeon_device *rdev) rdev->mc.agp_base = rdev->ddev->agp->agp_info.aper_base; rdev->mc.gtt_size = rdev->ddev->agp->agp_info.aper_size << 20; + rdev->mc.gtt_start = rdev->mc.agp_base; + rdev->mc.gtt_end = rdev->mc.gtt_start + rdev->mc.gtt_size - 1; + dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", + rdev->mc.gtt_size >> 20, rdev->mc.gtt_start, rdev->mc.gtt_end); /* workaround some hw issues */ if (rdev->family < CHIP_R200) { @@ -244,7 +248,7 @@ int radeon_agp_init(struct radeon_device *rdev) } return 0; #else - return 0; + return -1; #endif } diff --git a/drivers/video/drm/radeon/radeon_asic.h b/drivers/video/drm/radeon/radeon_asic.h index a80a9c070b..6ea4b84ca1 100644 --- a/drivers/video/drm/radeon/radeon_asic.h +++ b/drivers/video/drm/radeon/radeon_asic.h @@ -43,7 +43,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); /* - * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 + * r100,rv100,rs100,rv200,rs200 */ extern int r100_init(struct radeon_device *rdev); extern void r100_fini(struct radeon_device *rdev); @@ -103,6 +103,52 @@ static struct radeon_asic r100_asic = { // .cs_parse = &r100_cs_parse, // .copy_blit = &r100_copy_blit, // .copy_dma = NULL, +// .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +/* + * r200,rv250,rs300,rv280 + */ +extern int r200_copy_dma(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, + unsigned num_pages, + struct radeon_fence *fence); +static struct radeon_asic r200_asic = { + .init = &r100_init, +// .fini = &r100_fini, +// .suspend = &r100_suspend, +// .resume = &r100_resume, +// .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r100_gpu_reset, + .gart_tlb_flush = &r100_pci_gart_tlb_flush, + .gart_set_page = &r100_pci_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r100_ring_start, + .ring_test = &r100_ring_test, +// .ring_ib_execute = &r100_ring_ib_execute, +// .irq_set = &r100_irq_set, +// .irq_process = &r100_irq_process, +// .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r100_fence_ring_emit, +// .cs_parse = &r100_cs_parse, +// .copy_blit = &r100_copy_blit, +// .copy_dma = NULL, // .copy = &r100_copy_blit, .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, @@ -138,11 +184,8 @@ extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg); extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); -extern int r300_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_pages, - struct radeon_fence *fence); +extern int rv370_get_pcie_lanes(struct radeon_device *rdev); + static struct radeon_asic r300_asic = { .init = &r300_init, // .fini = &r300_fini, @@ -163,6 +206,45 @@ static struct radeon_asic r300_asic = { // .cs_parse = &r300_cs_parse, // .copy_blit = &r100_copy_blit, // .copy_dma = &r300_copy_dma, +// .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + + +static struct radeon_asic r300_asic_pcie = { + .init = &r300_init, +// .fini = &r300_fini, +// .suspend = &r300_suspend, +// .resume = &r300_resume, +// .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, +// .ring_ib_execute = &r100_ring_ib_execute, +// .irq_set = &r100_irq_set, +// .irq_process = &r100_irq_process, +// .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, +// .cs_parse = &r300_cs_parse, +// .copy_blit = &r100_copy_blit, +// .copy_dma = &r300_copy_dma, // .copy = &r100_copy_blit, .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, @@ -212,6 +294,7 @@ static struct radeon_asic r420_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, .set_surface_reg = r100_set_surface_reg, @@ -261,6 +344,7 @@ static struct radeon_asic rs400_asic = { .set_engine_clock = &radeon_legacy_set_engine_clock, .get_memory_clock = &radeon_legacy_get_memory_clock, .set_memory_clock = NULL, + .get_pcie_lanes = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_legacy_set_clock_gating, .set_surface_reg = r100_set_surface_reg, @@ -320,8 +404,11 @@ static struct radeon_asic rs600_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, .bandwidth_update = &rs600_bandwidth_update, .hpd_init = &rs600_hpd_init, .hpd_fini = &rs600_hpd_fini, @@ -366,6 +453,7 @@ static struct radeon_asic rs690_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, .set_surface_reg = r100_set_surface_reg, @@ -418,6 +506,7 @@ static struct radeon_asic rv515_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, .set_surface_reg = r100_set_surface_reg, @@ -461,6 +550,7 @@ static struct radeon_asic r520_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, .set_surface_reg = r100_set_surface_reg, @@ -537,8 +627,9 @@ static struct radeon_asic r600_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, + .set_clock_gating = NULL, .set_surface_reg = r600_set_surface_reg, .clear_surface_reg = r600_clear_surface_reg, .bandwidth_update = &rv515_bandwidth_update, @@ -581,6 +672,7 @@ static struct radeon_asic rv770_asic = { .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, .set_surface_reg = r600_set_surface_reg, @@ -590,7 +682,55 @@ static struct radeon_asic rv770_asic = { .hpd_fini = &r600_hpd_fini, .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, -// .ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +/* + * evergreen + */ +int evergreen_init(struct radeon_device *rdev); +void evergreen_fini(struct radeon_device *rdev); +int evergreen_suspend(struct radeon_device *rdev); +int evergreen_resume(struct radeon_device *rdev); +int evergreen_gpu_reset(struct radeon_device *rdev); +void evergreen_bandwidth_update(struct radeon_device *rdev); +void evergreen_hpd_init(struct radeon_device *rdev); +void evergreen_hpd_fini(struct radeon_device *rdev); +bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); +void evergreen_hpd_set_polarity(struct radeon_device *rdev, + enum radeon_hpd_id hpd); + +static struct radeon_asic evergreen_asic = { + .init = &evergreen_init, +// .fini = &evergreen_fini, +// .suspend = &evergreen_suspend, +// .resume = &evergreen_resume, + .cp_commit = NULL, + .gpu_reset = &evergreen_gpu_reset, + .vga_set_state = &r600_vga_set_state, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .ring_test = NULL, +// .ring_ib_execute = &r600_ring_ib_execute, +// .irq_set = &r600_irq_set, +// .irq_process = &r600_irq_process, + .fence_ring_emit = &r600_fence_ring_emit, +// .cs_parse = &r600_cs_parse, +// .copy_blit = &r600_copy_blit, +// .copy_dma = &r600_copy_blit, +// .copy = &r600_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &evergreen_bandwidth_update, + .hpd_init = &evergreen_hpd_init, + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, }; #endif diff --git a/drivers/video/drm/radeon/radeon_atombios.c b/drivers/video/drm/radeon/radeon_atombios.c index 32225febb1..1ca0fda4c2 100644 --- a/drivers/video/drm/radeon/radeon_atombios.c +++ b/drivers/video/drm/radeon/radeon_atombios.c @@ -159,8 +159,15 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device struct radeon_gpio_rec *gpio) { struct radeon_hpd hpd; + u32 reg; + + if (ASIC_IS_DCE4(rdev)) + reg = EVERGREEN_DC_GPIO_HPD_A; + else + reg = AVIVO_DC_GPIO_HPD_A; + hpd.gpio = *gpio; - if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { + if (gpio->reg == reg) { switch(gpio->mask) { case (1 << 0): hpd.hpd = RADEON_HPD_1; @@ -574,6 +581,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ddc_bus.valid = false; } + /* needed for aux chan transactions */ + ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0; + conn_id = le16_to_cpu(path->usConnObjectId); if (!radeon_atom_apply_quirks @@ -838,6 +848,7 @@ union firmware_info { ATOM_FIRMWARE_INFO_V1_2 info_12; ATOM_FIRMWARE_INFO_V1_3 info_13; ATOM_FIRMWARE_INFO_V1_4 info_14; + ATOM_FIRMWARE_INFO_V2_1 info_21; }; bool radeon_atom_get_clock_info(struct drm_device *dev) @@ -849,6 +860,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) uint8_t frev, crev; struct radeon_pll *p1pll = &rdev->clock.p1pll; struct radeon_pll *p2pll = &rdev->clock.p2pll; + struct radeon_pll *dcpll = &rdev->clock.dcpll; struct radeon_pll *spll = &rdev->clock.spll; struct radeon_pll *mpll = &rdev->clock.mpll; uint16_t data_offset; @@ -951,8 +963,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) rdev->clock.default_mclk = le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); + if (ASIC_IS_DCE4(rdev)) { + rdev->clock.default_dispclk = + le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); + if (rdev->clock.default_dispclk == 0) + rdev->clock.default_dispclk = 60000; /* 600 Mhz */ + rdev->clock.dp_extclk = + le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); + } + *dcpll = *p1pll; + return true; } + return false; } @@ -1091,6 +1114,30 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct return ss; } +static void radeon_atom_apply_lvds_quirks(struct drm_device *dev, + struct radeon_encoder_atom_dig *lvds) +{ + + /* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */ + if ((dev->pdev->device == 0x95c4) && + (dev->pdev->subsystem_vendor == 0x1179) && + (dev->pdev->subsystem_device == 0xff50)) { + if ((lvds->native_mode.hdisplay == 1280) && + (lvds->native_mode.vdisplay == 800)) + lvds->pll_algo = PLL_ALGO_LEGACY; + } + + /* Dell Studio 15 laptop panel doesn't like new pll divider algo */ + if ((dev->pdev->device == 0x95c4) && + (dev->pdev->subsystem_vendor == 0x1028) && + (dev->pdev->subsystem_device == 0x029f)) { + if ((lvds->native_mode.hdisplay == 1280) && + (lvds->native_mode.vdisplay == 800)) + lvds->pll_algo = PLL_ALGO_LEGACY; + } + +} + union lvds_info { struct _ATOM_LVDS_INFO info; struct _ATOM_LVDS_INFO_V12 info_12; @@ -1161,6 +1208,21 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); + if (ASIC_IS_AVIVO(rdev)) { + if (radeon_new_pll == 0) + lvds->pll_algo = PLL_ALGO_LEGACY; + else + lvds->pll_algo = PLL_ALGO_NEW; + } else { + if (radeon_new_pll == 1) + lvds->pll_algo = PLL_ALGO_NEW; + else + lvds->pll_algo = PLL_ALGO_LEGACY; + } + + /* LVDS quirks */ + radeon_atom_apply_lvds_quirks(dev, lvds); + encoder->native_mode = lvds->native_mode; } return lvds; @@ -1385,6 +1447,371 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) return tv_dac; } +union power_info { + struct _ATOM_POWERPLAY_INFO info; + struct _ATOM_POWERPLAY_INFO_V2 info_2; + struct _ATOM_POWERPLAY_INFO_V3 info_3; + struct _ATOM_PPLIB_POWERPLAYTABLE info_4; +}; + +void radeon_atombios_get_power_modes(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); + u16 data_offset; + u8 frev, crev; + u32 misc, misc2 = 0, sclk, mclk; + union power_info *power_info; + struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; + struct _ATOM_PPLIB_STATE *power_state; + int num_modes = 0, i, j; + int state_index = 0, mode_index = 0; + + atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); + + power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); + + rdev->pm.default_power_state = NULL; + + if (power_info) { + if (frev < 4) { + num_modes = power_info->info.ucNumOfPowerModeEntries; + if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) + num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; + for (i = 0; i < num_modes; i++) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + switch (frev) { + case 1: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = + power_info->info.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; + } + /* order matters! */ + if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_POWERSAVE; + if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[0]; + } + state_index++; + break; + case 2: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = + power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); + misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; + } + /* order matters! */ + if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_POWERSAVE; + if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[0]; + } + state_index++; + break; + case 3: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = + power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); + misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; + if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { + rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = + true; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = + power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; + } + } + /* order matters! */ + if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_POWERSAVE; + if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[0]; + } + state_index++; + break; + } + } + } else if (frev == 4) { + for (i = 0; i < power_info->info_4.ucNumStates; i++) { + mode_index = 0; + power_state = (struct _ATOM_PPLIB_STATE *) + (mode_info->atom_context->bios + + data_offset + + le16_to_cpu(power_info->info_4.usStateArrayOffset) + + i * power_info->info_4.ucStateEntrySize); + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + (mode_info->atom_context->bios + + data_offset + + le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + + (power_state->ucNonClockStateIndex * + power_info->info_4.ucNonClockSize)); + for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { + if (rdev->flags & RADEON_IS_IGP) { + struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = + (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) + (mode_info->atom_context->bios + + data_offset + + le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + + (power_state->ucClockStateIndices[j] * + power_info->info_4.ucClockInfoSize)); + sclk = le16_to_cpu(clock_info->usLowEngineClockLow); + sclk |= clock_info->ucLowEngineClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + /* skip invalid modes */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) + continue; + /* skip overclock modes for now */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN) + continue; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = + VOLTAGE_SW; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = + clock_info->usVDDC; + mode_index++; + } else { + struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = + (struct _ATOM_PPLIB_R600_CLOCK_INFO *) + (mode_info->atom_context->bios + + data_offset + + le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + + (power_state->ucClockStateIndices[j] * + power_info->info_4.ucClockInfoSize)); + sclk = le16_to_cpu(clock_info->usEngineClockLow); + sclk |= clock_info->ucEngineClockHigh << 16; + mclk = le16_to_cpu(clock_info->usMemoryClockLow); + mclk |= clock_info->ucMemoryClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) + continue; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + continue; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = + VOLTAGE_SW; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = + clock_info->usVDDC; + mode_index++; + } + } + rdev->pm.power_state[state_index].num_clock_modes = mode_index; + if (mode_index) { + misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); + misc2 = le16_to_cpu(non_clock_info->usClassification); + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = + ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> + ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; + switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { + case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + break; + case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + break; + case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + break; + } + if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; + } + state_index++; + } + } + } + } else { + /* XXX figure out some good default low power mode for cards w/out power tables */ + } + + if (rdev->pm.default_power_state == NULL) { + /* add the default mode */ + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; + rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[0]; + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + if (rdev->asic->get_pcie_lanes) + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); + else + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + state_index++; + } + rdev->pm.num_power_states = state_index; + + rdev->pm.current_power_state = rdev->pm.default_power_state; + rdev->pm.current_clock_mode = + rdev->pm.default_power_state->default_clock_mode; +} + void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) { DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; @@ -1395,16 +1822,6 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } -void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable) -{ - ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt); - - args.ucEnable = enable; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) { GET_ENGINE_CLOCK_PS_ALLOCATION args; diff --git a/drivers/video/drm/radeon/radeon_bios.c b/drivers/video/drm/radeon/radeon_bios.c index d0cf57a7bf..87884ddc98 100644 --- a/drivers/video/drm/radeon/radeon_bios.c +++ b/drivers/video/drm/radeon/radeon_bios.c @@ -93,6 +93,38 @@ static bool radeon_read_bios(struct radeon_device *rdev) return true; } +/* ATRM is used to get the BIOS on the discrete cards in + * dual-gpu systems. + */ +static bool radeon_atrm_get_bios(struct radeon_device *rdev) +{ + int ret; + int size = 64 * 1024; + int i; + + if (!radeon_atrm_supported(rdev->pdev)) + return false; + + rdev->bios = kmalloc(size, GFP_KERNEL); + if (!rdev->bios) { + DRM_ERROR("Unable to allocate bios\n"); + return false; + } + + for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { + ret = radeon_atrm_get_bios_chunk(rdev->bios, + (i * ATRM_BIOS_PAGE), + ATRM_BIOS_PAGE); + if (ret <= 0) + break; + } + + if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { + kfree(rdev->bios); + return false; + } + return true; +} static bool r700_read_disabled_bios(struct radeon_device *rdev) { uint32_t viph_control; @@ -388,17 +420,17 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) return legacy_read_disabled_bios(rdev); } + bool radeon_get_bios(struct radeon_device *rdev) { bool r; uint16_t tmp; - if (rdev->flags & RADEON_IS_IGP) { + r = radeon_atrm_get_bios(rdev); + if (r == false) r = igp_read_bios_from_vram(rdev); if (r == false) r = radeon_read_bios(rdev); - } else - r = radeon_read_bios(rdev); if (r == false) { r = radeon_read_disabled_bios(rdev); } @@ -408,6 +440,13 @@ bool radeon_get_bios(struct radeon_device *rdev) return false; } if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { + printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]); + goto free_bios; + } + + tmp = RBIOS16(0x18); + if (RBIOS8(tmp + 0x14) != 0x0) { + DRM_INFO("Not an x86 BIOS ROM, not using.\n"); goto free_bios; } diff --git a/drivers/video/drm/radeon/radeon_clocks.c b/drivers/video/drm/radeon/radeon_clocks.c index d3ddbb1cca..544f179439 100644 --- a/drivers/video/drm/radeon/radeon_clocks.c +++ b/drivers/video/drm/radeon/radeon_clocks.c @@ -96,6 +96,7 @@ void radeon_get_clock_info(struct drm_device *dev) struct radeon_device *rdev = dev->dev_private; struct radeon_pll *p1pll = &rdev->clock.p1pll; struct radeon_pll *p2pll = &rdev->clock.p2pll; + struct radeon_pll *dcpll = &rdev->clock.dcpll; struct radeon_pll *spll = &rdev->clock.spll; struct radeon_pll *mpll = &rdev->clock.mpll; int ret; @@ -204,6 +205,17 @@ void radeon_get_clock_info(struct drm_device *dev) p2pll->max_frac_feedback_div = 0; } + /* dcpll is DCE4 only */ + dcpll->min_post_div = 2; + dcpll->max_post_div = 0x7f; + dcpll->min_frac_feedback_div = 0; + dcpll->max_frac_feedback_div = 9; + dcpll->min_ref_div = 2; + dcpll->max_ref_div = 0x3ff; + dcpll->min_feedback_div = 4; + dcpll->max_feedback_div = 0xfff; + dcpll->best_vco = 0; + p1pll->min_ref_div = 2; p1pll->max_ref_div = 0x3ff; p1pll->min_feedback_div = 4; @@ -846,8 +858,10 @@ int radeon_static_clocks_init(struct drm_device *dev) /* XXX make sure engine is idle */ if (radeon_dynclks != -1) { - if (radeon_dynclks) + if (radeon_dynclks) { + if (rdev->asic->set_clock_gating) radeon_set_clock_gating(rdev, 1); + } } radeon_apply_clock_quirks(rdev); return 0; diff --git a/drivers/video/drm/radeon/radeon_combios.c b/drivers/video/drm/radeon/radeon_combios.c index fa91474bf7..bf54004ae3 100644 --- a/drivers/video/drm/radeon/radeon_combios.c +++ b/drivers/video/drm/radeon/radeon_combios.c @@ -150,6 +150,9 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, int rev; uint16_t offset = 0, check_offset; + if (!rdev->bios) + return 0; + switch (table) { /* absolute offset tables */ case COMBIOS_ASIC_INIT_1_TABLE: @@ -443,6 +446,39 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, } +bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) +{ + int edid_info; + struct edid *edid; + edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); + if (!edid_info) + return false; + + edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1), + GFP_KERNEL); + if (edid == NULL) + return false; + + memcpy((unsigned char *)edid, + (unsigned char *)(rdev->bios + edid_info), EDID_LENGTH); + + if (!drm_edid_is_valid(edid)) { + kfree(edid); + return false; + } + + rdev->mode_info.bios_hardcoded_edid = edid; + return true; +} + +struct edid * +radeon_combios_get_hardcoded_edid(struct radeon_device *rdev) +{ + if (rdev->mode_info.bios_hardcoded_edid) + return rdev->mode_info.bios_hardcoded_edid; + return NULL; +} + static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, int ddc_line) { @@ -486,9 +522,65 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde i2c.y_data_reg = ddc_line; } - if (rdev->family < CHIP_R200) + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + case CHIP_RS300: + switch (ddc_line) { + case RADEON_GPIO_DVI_DDC: + /* in theory this should be hw capable, + * but it doesn't seem to work + */ + i2c.hw_capable = false; + break; + default: + i2c.hw_capable = false; + break; + } + break; + case CHIP_R200: + switch (ddc_line) { + case RADEON_GPIO_DVI_DDC: + case RADEON_GPIO_MONID: + i2c.hw_capable = true; + break; + default: + i2c.hw_capable = false; + break; + } + break; + case CHIP_RV250: + case CHIP_RV280: + switch (ddc_line) { + case RADEON_GPIO_VGA_DDC: + case RADEON_GPIO_DVI_DDC: + case RADEON_GPIO_CRT2_DDC: + i2c.hw_capable = true; + break; + default: + i2c.hw_capable = false; + break; + } + break; + case CHIP_R300: + case CHIP_R350: + switch (ddc_line) { + case RADEON_GPIO_VGA_DDC: + case RADEON_GPIO_DVI_DDC: + i2c.hw_capable = true; + break; + default: i2c.hw_capable = false; - else { + break; + } + break; + case CHIP_RV350: + case CHIP_RV380: + case CHIP_RS400: + case CHIP_RS480: switch (ddc_line) { case RADEON_GPIO_VGA_DDC: case RADEON_GPIO_DVI_DDC: @@ -504,9 +596,14 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde i2c.hw_capable = false; break; } + break; + default: + i2c.hw_capable = false; + break; } i2c.mm_i2c = false; i2c.i2c_id = 0; + i2c.hpd_id = 0; if (ddc_line) i2c.valid = true; @@ -527,9 +624,6 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) int8_t rev; uint16_t sclk, mclk; - if (rdev->bios == NULL) - return false; - pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); if (pll_info) { rev = RBIOS8(pll_info); @@ -654,9 +748,6 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct if (!p_dac) return NULL; - if (rdev->bios == NULL) - goto out; - /* check CRT table */ dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); if (dac_info) { @@ -673,7 +764,6 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct found = 1; } -out: if (!found) /* fallback to defaults */ radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); @@ -687,9 +777,6 @@ radeon_combios_get_tv_info(struct radeon_device *rdev) uint16_t tv_info; enum radeon_tv_std tv_std = TV_STD_NTSC; - if (rdev->bios == NULL) - return tv_std; - tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); if (tv_info) { if (RBIOS8(tv_info + 6) == 'T') { @@ -793,9 +880,6 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct if (!tv_dac) return NULL; - if (rdev->bios == NULL) - goto out; - /* first check TV table */ dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); if (dac_info) { @@ -857,7 +941,6 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct } } -out: if (!found) /* fallback to defaults */ radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac); @@ -945,11 +1028,6 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder int tmp, i; struct radeon_encoder_lvds *lvds = NULL; - if (rdev->bios == NULL) { - lvds = radeon_legacy_get_lvds_info_from_regs(rdev); - goto out; - } - lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); if (lcd_info) { @@ -1050,7 +1128,7 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder DRM_INFO("No panel info found in BIOS\n"); lvds = radeon_legacy_get_lvds_info_from_regs(rdev); } -out: + if (lvds) encoder->native_mode = lvds->native_mode; return lvds; @@ -1102,9 +1180,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, int i, n; uint8_t ver; - if (rdev->bios == NULL) - return false; - tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); if (tmds_info) { @@ -1184,9 +1259,6 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder enum radeon_combios_ddc gpio; struct radeon_i2c_bus_rec i2c_bus; - if (rdev->bios == NULL) - return false; - tmds->i2c_bus = NULL; if (rdev->flags & RADEON_IS_IGP) { offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); @@ -1253,7 +1325,10 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); break; case DDC_LCD: /* MM i2c */ - DRM_ERROR("MM i2c requires hw i2c engine\n"); + i2c_bus.valid = true; + i2c_bus.hw_capable = true; + i2c_bus.mm_i2c = true; + tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); break; default: DRM_ERROR("Unsupported gpio %d\n", gpio); @@ -1279,47 +1354,47 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) rdev->mode_info.connector_table = radeon_connector_table; if (rdev->mode_info.connector_table == CT_NONE) { #ifdef CONFIG_PPC_PMAC - if (machine_is_compatible("PowerBook3,3")) { + if (of_machine_is_compatible("PowerBook3,3")) { /* powerbook with VGA */ rdev->mode_info.connector_table = CT_POWERBOOK_VGA; - } else if (machine_is_compatible("PowerBook3,4") || - machine_is_compatible("PowerBook3,5")) { + } else if (of_machine_is_compatible("PowerBook3,4") || + of_machine_is_compatible("PowerBook3,5")) { /* powerbook with internal tmds */ rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL; - } else if (machine_is_compatible("PowerBook5,1") || - machine_is_compatible("PowerBook5,2") || - machine_is_compatible("PowerBook5,3") || - machine_is_compatible("PowerBook5,4") || - machine_is_compatible("PowerBook5,5")) { + } else if (of_machine_is_compatible("PowerBook5,1") || + of_machine_is_compatible("PowerBook5,2") || + of_machine_is_compatible("PowerBook5,3") || + of_machine_is_compatible("PowerBook5,4") || + of_machine_is_compatible("PowerBook5,5")) { /* powerbook with external single link tmds (sil164) */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook5,6")) { + } else if (of_machine_is_compatible("PowerBook5,6")) { /* powerbook with external dual or single link tmds */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook5,7") || - machine_is_compatible("PowerBook5,8") || - machine_is_compatible("PowerBook5,9")) { + } else if (of_machine_is_compatible("PowerBook5,7") || + of_machine_is_compatible("PowerBook5,8") || + of_machine_is_compatible("PowerBook5,9")) { /* PowerBook6,2 ? */ /* powerbook with external dual link tmds (sil1178?) */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook4,1") || - machine_is_compatible("PowerBook4,2") || - machine_is_compatible("PowerBook4,3") || - machine_is_compatible("PowerBook6,3") || - machine_is_compatible("PowerBook6,5") || - machine_is_compatible("PowerBook6,7")) { + } else if (of_machine_is_compatible("PowerBook4,1") || + of_machine_is_compatible("PowerBook4,2") || + of_machine_is_compatible("PowerBook4,3") || + of_machine_is_compatible("PowerBook6,3") || + of_machine_is_compatible("PowerBook6,5") || + of_machine_is_compatible("PowerBook6,7")) { /* ibook */ rdev->mode_info.connector_table = CT_IBOOK; - } else if (machine_is_compatible("PowerMac4,4")) { + } else if (of_machine_is_compatible("PowerMac4,4")) { /* emac */ rdev->mode_info.connector_table = CT_EMAC; - } else if (machine_is_compatible("PowerMac10,1")) { + } else if (of_machine_is_compatible("PowerMac10,1")) { /* mini with internal tmds */ rdev->mode_info.connector_table = CT_MINI_INTERNAL; - } else if (machine_is_compatible("PowerMac10,2")) { + } else if (of_machine_is_compatible("PowerMac10,2")) { /* mini with external tmds */ rdev->mode_info.connector_table = CT_MINI_EXTERNAL; - } else if (machine_is_compatible("PowerMac12,1")) { + } else if (of_machine_is_compatible("PowerMac12,1")) { /* PowerMac8,1 ? */ /* imac g5 isight */ rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; @@ -1909,9 +1984,6 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) struct radeon_i2c_bus_rec ddc_i2c; struct radeon_hpd hpd; - if (rdev->bios == NULL) - return false; - conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE); if (conn_info) { for (i = 0; i < 4; i++) { @@ -2278,6 +2350,115 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) return true; } +void radeon_combios_get_power_modes(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + u16 offset, misc, misc2 = 0; + u8 rev, blocks, tmp; + int state_index = 0; + + rdev->pm.default_power_state = NULL; + + if (rdev->flags & RADEON_IS_MOBILITY) { + offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); + if (offset) { + rev = RBIOS8(offset); + blocks = RBIOS8(offset + 0x2); + /* power mode 0 tends to be the only valid one */ + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2); + rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6); + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + goto default_mode; + /* skip overclock modes for now */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk > + rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || + (rdev->pm.power_state[state_index].clock_info[0].sclk > + rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) + goto default_mode; + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + misc = RBIOS16(offset + 0x5 + 0x0); + if (rev > 4) + misc2 = RBIOS16(offset + 0x5 + 0xe); + if (misc & 0x4) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; + if (misc & 0x8) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true; + if (rev < 6) { + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = + RBIOS16(offset + 0x5 + 0xb) * 4; + tmp = RBIOS8(offset + 0x5 + 0xd); + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); + } else { + u8 entries = RBIOS8(offset + 0x5 + 0xb); + u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc); + if (entries && voltage_table_offset) { + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = + RBIOS16(voltage_table_offset) * 4; + tmp = RBIOS8(voltage_table_offset + 0x2); + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); + } else + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false; + } + switch ((misc2 & 0x700) >> 8) { + case 0: + default: + rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0; + break; + case 1: + rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33; + break; + case 2: + rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66; + break; + case 3: + rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99; + break; + case 4: + rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132; + break; + } + } else + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + if (rev > 6) + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = + RBIOS8(offset + 0x5 + 0x10); + state_index++; + } else { + /* XXX figure out some good default low power mode for mobility cards w/out power tables */ + } + } else { + /* XXX figure out some good default low power mode for desktop cards */ + } + +default_mode: + /* add the default mode */ + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; + rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; + rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + if (rdev->asic->get_pcie_lanes) + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); + else + rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; + rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; + rdev->pm.num_power_states = state_index + 1; + + rdev->pm.current_power_state = rdev->pm.default_power_state; + rdev->pm.current_clock_mode = + rdev->pm.default_power_state->default_clock_mode; +} + void radeon_external_tmds_setup(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -2289,23 +2470,21 @@ void radeon_external_tmds_setup(struct drm_encoder *encoder) switch (tmds->dvo_chip) { case DVO_SIL164: /* sil 164 */ - radeon_i2c_do_lock(tmds->i2c_bus, 1); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, 0x08, 0x30); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, 0x09, 0x00); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, 0x0a, 0x90); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, 0x0c, 0x89); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, 0x08, 0x3b); - radeon_i2c_do_lock(tmds->i2c_bus, 0); break; case DVO_SIL1178: /* sil 1178 - untested */ @@ -2338,9 +2517,6 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) uint32_t reg, val, and_mask, or_mask; struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; - if (rdev->bios == NULL) - return false; - if (!tmds) return false; @@ -2390,11 +2566,9 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) index++; val = RBIOS8(index); index++; - radeon_i2c_do_lock(tmds->i2c_bus, 1); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, slave_addr, reg, val); - radeon_i2c_do_lock(tmds->i2c_bus, 0); break; default: DRM_ERROR("Unknown id %d\n", id >> 13); @@ -2447,11 +2621,9 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) reg = id & 0x1fff; val = RBIOS8(index); index += 1; - radeon_i2c_do_lock(tmds->i2c_bus, 1); - radeon_i2c_sw_put_byte(tmds->i2c_bus, + radeon_i2c_put_byte(tmds->i2c_bus, tmds->slave_addr, reg, val); - radeon_i2c_do_lock(tmds->i2c_bus, 0); break; default: DRM_ERROR("Unknown id %d\n", id >> 13); diff --git a/drivers/video/drm/radeon/radeon_connectors.c b/drivers/video/drm/radeon/radeon_connectors.c index 52c94d208e..74fc2ca5f3 100644 --- a/drivers/video/drm/radeon/radeon_connectors.c +++ b/drivers/video/drm/radeon/radeon_connectors.c @@ -479,10 +479,8 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec ret = connector_status_connected; else { if (radeon_connector->ddc_bus) { - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); if (radeon_connector->edid) ret = connector_status_connected; } @@ -587,19 +585,14 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect if (!encoder) ret = connector_status_disconnected; - if (radeon_connector->ddc_bus) { - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); + if (radeon_connector->ddc_bus) dret = radeon_ddc_probe(radeon_connector); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); - } if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); radeon_connector->edid = NULL; } - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", @@ -744,19 +737,14 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect enum drm_connector_status ret = connector_status_disconnected; bool dret = false; - if (radeon_connector->ddc_bus) { - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); + if (radeon_connector->ddc_bus) dret = radeon_ddc_probe(radeon_connector); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); - } if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); radeon_connector->edid = NULL; } - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", @@ -952,7 +940,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) if (radeon_connector->edid) kfree(radeon_connector->edid); if (radeon_dig_connector->dp_i2c_bus) - radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); + radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus); kfree(radeon_connector->con_priv); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -988,12 +976,10 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto ret = connector_status_connected; } } else { - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); if (radeon_ddc_probe(radeon_connector)) { radeon_dig_connector->dp_sink_type = sink_type; ret = connector_status_connected; } - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); } return ret; diff --git a/drivers/video/drm/radeon/radeon_device.c b/drivers/video/drm/radeon/radeon_device.c index 6d82322e41..fe6f8a0820 100644 --- a/drivers/video/drm/radeon/radeon_device.c +++ b/drivers/video/drm/radeon/radeon_device.c @@ -39,17 +39,21 @@ #include -int radeon_dynclks = -1; -int radeon_r4xx_atom = 0; -int radeon_agpmode = -1; -int radeon_gart_size = 512; /* default gart size */ -int radeon_benchmarking = 0; -int radeon_connector_table = 0; -int radeon_tv = 0; -int radeon_modeset = 1; -int radeon_new_pll = 1; -int radeon_vram_limit = 0; -int radeon_audio = 0; +int radeon_no_wb; +int radeon_modeset = -1; +int radeon_dynclks = -1; +int radeon_r4xx_atom = 0; +int radeon_agpmode = 0; +int radeon_vram_limit = 0; +int radeon_gart_size = 512; /* default gart size */ +int radeon_benchmarking = 0; +int radeon_testing = 0; +int radeon_connector_table = 0; +int radeon_tv = 1; +int radeon_new_pll = -1; +int radeon_dynpm = -1; +int radeon_audio = 1; + extern display_t *rdisplay; @@ -135,79 +139,102 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) } } -/* - * MC common functions +/** + * radeon_vram_location - try to find VRAM location + * @rdev: radeon device structure holding all necessary informations + * @mc: memory controller structure holding memory informations + * @base: base address at which to put VRAM + * + * Function will place try to place VRAM at base address provided + * as parameter (which is so far either PCI aperture address or + * for IGP TOM base address). + * + * If there is not enough space to fit the unvisible VRAM in the 32bits + * address space then we limit the VRAM size to the aperture. + * + * If we are using AGP and if the AGP aperture doesn't allow us to have + * room for all the VRAM than we restrict the VRAM to the PCI aperture + * size and print a warning. + * + * This function will never fails, worst case are limiting VRAM. + * + * Note: GTT start, end, size should be initialized before calling this + * function on AGP platform. + * + * Note: We don't explictly enforce VRAM start to be aligned on VRAM size, + * this shouldn't be a problem as we are using the PCI aperture as a reference. + * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but + * not IGP. + * + * Note: we use mc_vram_size as on some board we need to program the mc to + * cover the whole aperture even if VRAM size is inferior to aperture size + * Novell bug 204882 + along with lots of ubuntu ones + * + * Note: when limiting vram it's safe to overwritte real_vram_size because + * we are not in case where real_vram_size is inferior to mc_vram_size (ie + * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu + * ones) + * + * Note: IGP TOM addr should be the same as the aperture addr, we don't + * explicitly check for that thought. + * + * FIXME: when reducing VRAM size align new size on power of 2. */ -int radeon_mc_setup(struct radeon_device *rdev) +void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) { - uint32_t tmp; - - /* Some chips have an "issue" with the memory controller, the - * location must be aligned to the size. We just align it down, - * too bad if we walk over the top of system memory, we don't - * use DMA without a remapped anyway. - * Affected chips are rv280, all r3xx, and all r4xx, but not IGP - */ - /* FGLRX seems to setup like this, VRAM a 0, then GART. - */ - /* - * Note: from R6xx the address space is 40bits but here we only - * use 32bits (still have to see a card which would exhaust 4G - * address space). - */ - if (rdev->mc.vram_location != 0xFFFFFFFFUL) { - /* vram location was already setup try to put gtt after - * if it fits */ - tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; - tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); - if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { - rdev->mc.gtt_location = tmp; - } else { - if (rdev->mc.gtt_size >= rdev->mc.vram_location) { - printk(KERN_ERR "[drm] GTT too big to fit " - "before or after vram location.\n"); - return -EINVAL; - } - rdev->mc.gtt_location = 0; - } - } else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) { - /* gtt location was already setup try to put vram before - * if it fits */ - if (rdev->mc.mc_vram_size < rdev->mc.gtt_location) { - rdev->mc.vram_location = 0; - } else { - tmp = rdev->mc.gtt_location + rdev->mc.gtt_size; - tmp += (rdev->mc.mc_vram_size - 1); - tmp &= ~(rdev->mc.mc_vram_size - 1); - if ((0xFFFFFFFFUL - tmp) >= rdev->mc.mc_vram_size) { - rdev->mc.vram_location = tmp; - } else { - printk(KERN_ERR "[drm] vram too big to fit " - "before or after GTT location.\n"); - return -EINVAL; - } - } - } else { - rdev->mc.vram_location = 0; - tmp = rdev->mc.mc_vram_size; - tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); - rdev->mc.gtt_location = tmp; + mc->vram_start = base; + if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { + dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); + mc->real_vram_size = mc->aper_size; + mc->mc_vram_size = mc->aper_size; } - rdev->mc.vram_start = rdev->mc.vram_location; - rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; - rdev->mc.gtt_start = rdev->mc.gtt_location; - rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; - DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20)); - DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", - (unsigned)rdev->mc.vram_location, - (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1)); - DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20)); - DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n", - (unsigned)rdev->mc.gtt_location, - (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1)); - return 0; + mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; + if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { + dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); + mc->real_vram_size = mc->aper_size; + mc->mc_vram_size = mc->aper_size; + } + mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; + dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", + mc->mc_vram_size >> 20, mc->vram_start, + mc->vram_end, mc->real_vram_size >> 20); } +/** + * radeon_gtt_location - try to find GTT location + * @rdev: radeon device structure holding all necessary informations + * @mc: memory controller structure holding memory informations + * + * Function will place try to place GTT before or after VRAM. + * + * If GTT size is bigger than space left then we ajust GTT size. + * Thus function will never fails. + * + * FIXME: when reducing GTT size align new size on power of 2. + */ +void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) +{ + u64 size_af, size_bf; + + size_af = 0xFFFFFFFF - mc->vram_end; + size_bf = mc->vram_start; + if (size_bf > size_af) { + if (mc->gtt_size > size_bf) { + dev_warn(rdev->dev, "limiting GTT\n"); + mc->gtt_size = size_bf; + } + mc->gtt_start = mc->vram_start - mc->gtt_size; + } else { + if (mc->gtt_size > size_af) { + dev_warn(rdev->dev, "limiting GTT\n"); + mc->gtt_size = size_af; + } + mc->gtt_start = mc->vram_end + 1; + } + mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; + dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", + mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); +} /* * GPU helpers function. @@ -217,7 +244,16 @@ bool radeon_card_posted(struct radeon_device *rdev) uint32_t reg; /* first check CRTCs */ - if (ASIC_IS_AVIVO(rdev)) { + if (ASIC_IS_DCE4(rdev)) { + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + if (reg & EVERGREEN_CRTC_MASTER_EN) + return true; + } else if (ASIC_IS_AVIVO(rdev)) { reg = RREG32(AVIVO_D1CRTC_CONTROL) | RREG32(AVIVO_D2CRTC_CONTROL); if (reg & AVIVO_CRTC_EN) { @@ -264,6 +300,8 @@ bool radeon_boot_test_post_card(struct radeon_device *rdev) int radeon_dummy_page_init(struct radeon_device *rdev) { + if (rdev->dummy_page.page) + return 0; rdev->dummy_page.page = AllocPage(); if (rdev->dummy_page.page == NULL) return -ENOMEM; @@ -342,7 +380,7 @@ void radeon_register_accessor_init(struct radeon_device *rdev) rdev->mc_rreg = &rs600_mc_rreg; rdev->mc_wreg = &rs600_mc_wreg; } - if (rdev->family >= CHIP_R600) { + if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { rdev->pciep_rreg = &r600_pciep_rreg; rdev->pciep_wreg = &r600_pciep_wreg; } @@ -361,21 +399,22 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_RS100: case CHIP_RV200: case CHIP_RS200: + rdev->asic = &r100_asic; + break; case CHIP_R200: case CHIP_RV250: case CHIP_RS300: case CHIP_RV280: - rdev->asic = &r100_asic; + rdev->asic = &r200_asic; break; case CHIP_R300: case CHIP_R350: case CHIP_RV350: case CHIP_RV380: + if (rdev->flags & RADEON_IS_PCIE) + rdev->asic = &r300_asic_pcie; + else rdev->asic = &r300_asic; - if (rdev->flags & RADEON_IS_PCIE) { - rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; - rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; - } break; case CHIP_R420: case CHIP_R423: @@ -419,6 +458,13 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_RV740: rdev->asic = &rv770_asic; break; + case CHIP_CEDAR: + case CHIP_REDWOOD: + case CHIP_JUNIPER: + case CHIP_CYPRESS: + case CHIP_HEMLOCK: + rdev->asic = &evergreen_asic; + break; default: /* FIXME: not supported yet */ return -EINVAL; @@ -714,6 +760,8 @@ int radeon_device_init(struct radeon_device *rdev, DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); /* if we have > 1 VGA cards, then disable the radeon VGA resources */ + /* this will fail for cards that aren't VGA class devices, just + * ignore it */ // r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); // if (r) { // return -EINVAL; @@ -986,7 +1034,7 @@ u32_t drvEntry(int action, char *cmdline) return 0; }; } - dbgprintf("Radeon RC9 cmdline %s\n", cmdline); + dbgprintf("Radeon RC10 cmdline %s\n", cmdline); enum_pci_devices(); @@ -1008,7 +1056,7 @@ u32_t drvEntry(int action, char *cmdline) if( (rdev->asic == &r600_asic) || (rdev->asic == &rv770_asic)) r600_2D_test(rdev); - else + else if (rdev->asic != &evergreen_asic) r100_2D_test(rdev); err = RegService("DISPLAY", display_handler); @@ -1018,3 +1066,10 @@ u32_t drvEntry(int action, char *cmdline) return err; }; + +void drm_vblank_post_modeset(struct drm_device *dev, int crtc) +{}; + +void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) +{}; + diff --git a/drivers/video/drm/radeon/radeon_display.c b/drivers/video/drm/radeon/radeon_display.c index 5b40dae761..f6cc326560 100644 --- a/drivers/video/drm/radeon/radeon_display.c +++ b/drivers/video/drm/radeon/radeon_display.c @@ -68,6 +68,36 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); } +static void evergreen_crtc_load_lut(struct drm_crtc *crtc) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + int i; + + DRM_DEBUG("%d\n", radeon_crtc->crtc_id); + WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); + + WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); + + WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); + WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); + WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); + + WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id); + WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007); + + WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0); + for (i = 0; i < 256; i++) { + WREG32(EVERGREEN_DC_LUT_30_COLOR, + (radeon_crtc->lut_r[i] << 20) | + (radeon_crtc->lut_g[i] << 10) | + (radeon_crtc->lut_b[i] << 0)); + } +} + static void legacy_crtc_load_lut(struct drm_crtc *crtc) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); @@ -100,7 +130,9 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc) if (!crtc->enabled) return; - if (ASIC_IS_AVIVO(rdev)) + if (ASIC_IS_DCE4(rdev)) + evergreen_crtc_load_lut(crtc); + else if (ASIC_IS_AVIVO(rdev)) avivo_crtc_load_lut(crtc); else legacy_crtc_load_lut(crtc); @@ -361,6 +393,8 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) { + struct drm_device *dev = radeon_connector->base.dev; + struct radeon_device *rdev = dev->dev_private; int ret = 0; if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || @@ -373,11 +407,11 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) if (!radeon_connector->ddc_bus) return -1; if (!radeon_connector->edid) { - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); } - + /* some servers provide a hardcoded edid in rom for KVMs */ + if (!radeon_connector->edid) + radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev); if (radeon_connector->edid) { drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); @@ -395,9 +429,7 @@ static int radeon_ddc_dump(struct drm_connector *connector) if (!radeon_connector->ddc_bus) return -1; - radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); - radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); if (edid) { kfree(edid); } @@ -414,7 +446,7 @@ static inline uint32_t radeon_div(uint64_t n, uint32_t d) return n; } -void radeon_compute_pll(struct radeon_pll *pll, +static void radeon_compute_pll_legacy(struct radeon_pll *pll, uint64_t freq, uint32_t *dot_clock_p, uint32_t *fb_div_p, @@ -580,7 +612,99 @@ void radeon_compute_pll(struct radeon_pll *pll, *post_div_p = best_post_div; } -void radeon_compute_pll_avivo(struct radeon_pll *pll, +static bool +calc_fb_div(struct radeon_pll *pll, + uint32_t freq, + uint32_t post_div, + uint32_t ref_div, + uint32_t *fb_div, + uint32_t *fb_div_frac) +{ + fixed20_12 feedback_divider, a, b; + u32 vco_freq; + + vco_freq = freq * post_div; + /* feedback_divider = vco_freq * ref_div / pll->reference_freq; */ + a.full = rfixed_const(pll->reference_freq); + feedback_divider.full = rfixed_const(vco_freq); + feedback_divider.full = rfixed_div(feedback_divider, a); + a.full = rfixed_const(ref_div); + feedback_divider.full = rfixed_mul(feedback_divider, a); + + if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { + /* feedback_divider = floor((feedback_divider * 10.0) + 0.5) * 0.1; */ + a.full = rfixed_const(10); + feedback_divider.full = rfixed_mul(feedback_divider, a); + feedback_divider.full += rfixed_const_half(0); + feedback_divider.full = rfixed_floor(feedback_divider); + feedback_divider.full = rfixed_div(feedback_divider, a); + + /* *fb_div = floor(feedback_divider); */ + a.full = rfixed_floor(feedback_divider); + *fb_div = rfixed_trunc(a); + /* *fb_div_frac = fmod(feedback_divider, 1.0) * 10.0; */ + a.full = rfixed_const(10); + b.full = rfixed_mul(feedback_divider, a); + + feedback_divider.full = rfixed_floor(feedback_divider); + feedback_divider.full = rfixed_mul(feedback_divider, a); + feedback_divider.full = b.full - feedback_divider.full; + *fb_div_frac = rfixed_trunc(feedback_divider); + } else { + /* *fb_div = floor(feedback_divider + 0.5); */ + feedback_divider.full += rfixed_const_half(0); + feedback_divider.full = rfixed_floor(feedback_divider); + + *fb_div = rfixed_trunc(feedback_divider); + *fb_div_frac = 0; + } + + if (((*fb_div) < pll->min_feedback_div) || ((*fb_div) > pll->max_feedback_div)) + return false; + else + return true; +} + +static bool +calc_fb_ref_div(struct radeon_pll *pll, + uint32_t freq, + uint32_t post_div, + uint32_t *fb_div, + uint32_t *fb_div_frac, + uint32_t *ref_div) +{ + fixed20_12 ffreq, max_error, error, pll_out, a; + u32 vco; + + ffreq.full = rfixed_const(freq); + /* max_error = ffreq * 0.0025; */ + a.full = rfixed_const(400); + max_error.full = rfixed_div(ffreq, a); + + for ((*ref_div) = pll->min_ref_div; (*ref_div) < pll->max_ref_div; ++(*ref_div)) { + if (calc_fb_div(pll, freq, post_div, (*ref_div), fb_div, fb_div_frac)) { + vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac)); + vco = vco / ((*ref_div) * 10); + + if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max)) + continue; + + /* pll_out = vco / post_div; */ + a.full = rfixed_const(post_div); + pll_out.full = rfixed_const(vco); + pll_out.full = rfixed_div(pll_out, a); + + if (pll_out.full >= ffreq.full) { + error.full = pll_out.full - ffreq.full; + if (error.full <= max_error.full) + return true; + } + } + } + return false; +} + +static void radeon_compute_pll_new(struct radeon_pll *pll, uint64_t freq, uint32_t *dot_clock_p, uint32_t *fb_div_p, @@ -588,87 +712,94 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, uint32_t *ref_div_p, uint32_t *post_div_p) { - fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; - fixed20_12 pll_out_max, pll_out_min; - fixed20_12 pll_in_max, pll_in_min; - fixed20_12 reference_freq; - fixed20_12 error, ffreq, a, b; + u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0; + u32 best_freq = 0, vco_frequency; - pll_out_max.full = rfixed_const(pll->pll_out_max); - pll_out_min.full = rfixed_const(pll->pll_out_min); - pll_in_max.full = rfixed_const(pll->pll_in_max); - pll_in_min.full = rfixed_const(pll->pll_in_min); - reference_freq.full = rfixed_const(pll->reference_freq); + /* freq = freq / 10; */ do_div(freq, 10); - ffreq.full = rfixed_const(freq); - error.full = rfixed_const(100 * 100); - /* max p */ - p.full = rfixed_div(pll_out_max, ffreq); - p.full = rfixed_floor(p); + if (pll->flags & RADEON_PLL_USE_POST_DIV) { + post_div = pll->post_div; + if ((post_div < pll->min_post_div) || (post_div > pll->max_post_div)) + goto done; - /* min m */ - m.full = rfixed_div(reference_freq, pll_in_max); - m.full = rfixed_ceil(m); + vco_frequency = freq * post_div; + if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) + goto done; - while (1) { - n.full = rfixed_div(ffreq, reference_freq); - n.full = rfixed_mul(n, m); - n.full = rfixed_mul(n, p); + if (pll->flags & RADEON_PLL_USE_REF_DIV) { + ref_div = pll->reference_div; + if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div)) + goto done; + if (!calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac)) + goto done; + } + } else { + for (post_div = pll->max_post_div; post_div >= pll->min_post_div; --post_div) { + if (pll->flags & RADEON_PLL_LEGACY) { + if ((post_div == 5) || + (post_div == 7) || + (post_div == 9) || + (post_div == 10) || + (post_div == 11)) + continue; + } - f_vco.full = rfixed_div(n, m); - f_vco.full = rfixed_mul(f_vco, reference_freq); - - f_pclk.full = rfixed_div(f_vco, p); - - if (f_pclk.full > ffreq.full) - error.full = f_pclk.full - ffreq.full; - else - error.full = ffreq.full - f_pclk.full; - error.full = rfixed_div(error, f_pclk); - a.full = rfixed_const(100 * 100); - error.full = rfixed_mul(error, a); - - a.full = rfixed_mul(m, p); - a.full = rfixed_div(n, a); - best_freq.full = rfixed_mul(reference_freq, a); - - if (rfixed_trunc(error) < 25) - break; - - a.full = rfixed_const(1); - m.full = m.full + a.full; - a.full = rfixed_div(reference_freq, m); - if (a.full >= pll_in_min.full) + if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) continue; - m.full = rfixed_div(reference_freq, pll_in_max); - m.full = rfixed_ceil(m); - a.full= rfixed_const(1); - p.full = p.full - a.full; - a.full = rfixed_mul(p, ffreq); - if (a.full >= pll_out_min.full) + vco_frequency = freq * post_div; + if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) continue; - else { - DRM_ERROR("Unable to find pll dividers\n"); + if (pll->flags & RADEON_PLL_USE_REF_DIV) { + ref_div = pll->reference_div; + if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div)) + goto done; + if (calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac)) + break; + } else { + if (calc_fb_ref_div(pll, freq, post_div, &fb_div, &fb_div_frac, &ref_div)) break; } } + } - a.full = rfixed_const(10); - b.full = rfixed_mul(n, a); + best_freq = pll->reference_freq * 10 * fb_div; + best_freq += pll->reference_freq * fb_div_frac; + best_freq = best_freq / (ref_div * post_div); - frac_n.full = rfixed_floor(n); - frac_n.full = rfixed_mul(frac_n, a); - frac_n.full = b.full - frac_n.full; +done: + if (best_freq == 0) + DRM_ERROR("Couldn't find valid PLL dividers\n"); - *dot_clock_p = rfixed_trunc(best_freq); - *fb_div_p = rfixed_trunc(n); - *frac_fb_div_p = rfixed_trunc(frac_n); - *ref_div_p = rfixed_trunc(m); - *post_div_p = rfixed_trunc(p); + *dot_clock_p = best_freq / 10; + *fb_div_p = fb_div; + *frac_fb_div_p = fb_div_frac; + *ref_div_p = ref_div; + *post_div_p = post_div; - DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); + DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); +} + +void radeon_compute_pll(struct radeon_pll *pll, + uint64_t freq, + uint32_t *dot_clock_p, + uint32_t *fb_div_p, + uint32_t *frac_fb_div_p, + uint32_t *ref_div_p, + uint32_t *post_div_p) +{ + switch (pll->algo) { + case PLL_ALGO_NEW: + radeon_compute_pll_new(pll, freq, dot_clock_p, fb_div_p, + frac_fb_div_p, ref_div_p, post_div_p); + break; + case PLL_ALGO_LEGACY: + default: + radeon_compute_pll_legacy(pll, freq, dot_clock_p, fb_div_p, + frac_fb_div_p, ref_div_p, post_div_p); + break; + } } static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) @@ -819,7 +950,7 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) int radeon_modeset_init(struct radeon_device *rdev) { - int num_crtc = 2, i; + int i; int ret; drm_mode_config_init(rdev->ddev); @@ -842,11 +973,23 @@ int radeon_modeset_init(struct radeon_device *rdev) return ret; } + /* check combios for a valid hardcoded EDID - Sun servers */ + if (!rdev->is_atom_bios) { + /* check for hardcoded EDID in BIOS */ + radeon_combios_check_hardcoded_edid(rdev); + } + if (rdev->flags & RADEON_SINGLE_CRTC) - num_crtc = 1; + rdev->num_crtc = 1; + else { + if (ASIC_IS_DCE4(rdev)) + rdev->num_crtc = 6; + else + rdev->num_crtc = 2; + } /* allocate crtcs */ - for (i = 0; i < num_crtc; i++) { + for (i = 0; i < rdev->num_crtc; i++) { radeon_crtc_init(rdev->ddev, i); } @@ -863,6 +1006,8 @@ int radeon_modeset_init(struct radeon_device *rdev) void radeon_modeset_fini(struct radeon_device *rdev) { + kfree(rdev->mode_info.bios_hardcoded_edid); + if (rdev->mode_info.mode_config_initialized) { radeon_hpd_fini(rdev); drm_mode_config_cleanup(rdev->ddev); diff --git a/drivers/video/drm/radeon/radeon_encoders.c b/drivers/video/drm/radeon/radeon_encoders.c index cdc255093c..648eed762c 100644 --- a/drivers/video/drm/radeon/radeon_encoders.c +++ b/drivers/video/drm/radeon/radeon_encoders.c @@ -228,6 +228,32 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) return NULL; } +static struct radeon_connector_atom_dig * +radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct drm_connector *connector; + struct radeon_connector *radeon_connector; + struct radeon_connector_atom_dig *dig_connector; + + if (!rdev->is_atom_bios) + return NULL; + + connector = radeon_get_connector_for_encoder(encoder); + if (!connector) + return NULL; + + radeon_connector = to_radeon_connector(connector); + + if (!radeon_connector->con_priv) + return NULL; + + dig_connector = radeon_connector->con_priv; + + return dig_connector; +} + static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -236,6 +262,9 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; + /* adjust pm to upcoming mode change */ + radeon_pm_compute_clocks(rdev); + /* set the active encoder to connector routing */ radeon_encoder_set_active_device(encoder); drm_mode_set_crtcinfo(adjusted_mode, 0); @@ -458,34 +487,20 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_connector_atom_dig *dig_connector = + radeon_get_atom_connector_priv_from_encoder(encoder); union lvds_encoder_control args; int index = 0; int hdmi_detected = 0; uint8_t frev, crev; - struct radeon_encoder_atom_dig *dig; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - connector = radeon_get_connector_for_encoder(encoder); - if (!connector) + if (!dig || !dig_connector) return; - radeon_connector = to_radeon_connector(connector); - - if (!radeon_encoder->enc_priv) - return; - - dig = radeon_encoder->enc_priv; - - if (!radeon_connector->con_priv) - return; - - if (drm_detect_hdmi_monitor(radeon_connector->edid)) + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) hdmi_detected = 1; - dig_connector = radeon_connector->con_priv; - memset(&args, 0, sizeof(args)); switch (radeon_encoder->encoder_id) { @@ -586,7 +601,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) { struct drm_connector *connector; struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *radeon_dig_connector; + struct radeon_connector_atom_dig *dig_connector; connector = radeon_get_connector_for_encoder(encoder); if (!connector) @@ -617,9 +632,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) break; case DRM_MODE_CONNECTOR_DisplayPort: case DRM_MODE_CONNECTOR_eDP: - radeon_dig_connector = radeon_connector->con_priv; - if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) + dig_connector = radeon_connector->con_priv; + if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || + (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) return ATOM_ENCODER_MODE_DP; else if (drm_detect_hdmi_monitor(radeon_connector->edid)) return ATOM_ENCODER_MODE_HDMI; @@ -656,6 +671,18 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * - 2 DIG encoder blocks. * DIG1/2 can drive UNIPHY0/1/2 link A or link B * + * DCE 4.0 + * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). + * Supports up to 6 digital outputs + * - 6 DIG encoder blocks. + * - DIG to PHY mapping is hardcoded + * DIG1 drives UNIPHY0 link A, A+B + * DIG2 drives UNIPHY0 link B + * DIG3 drives UNIPHY1 link A, A+B + * DIG4 drives UNIPHY1 link B + * DIG5 drives UNIPHY2 link A, A+B + * DIG6 drives UNIPHY2 link B + * * Routing * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) * Examples: @@ -664,87 +691,77 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI */ -static void + +union dig_encoder_control { + DIG_ENCODER_CONTROL_PS_ALLOCATION v1; + DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; + DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; +}; + +void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DIG_ENCODER_CONTROL_PS_ALLOCATION args; + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_connector_atom_dig *dig_connector = + radeon_get_atom_connector_priv_from_encoder(encoder); + union dig_encoder_control args; int index = 0, num = 0; uint8_t frev, crev; - struct radeon_encoder_atom_dig *dig; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - connector = radeon_get_connector_for_encoder(encoder); - if (!connector) + if (!dig || !dig_connector) return; - radeon_connector = to_radeon_connector(connector); - - if (!radeon_connector->con_priv) - return; - - dig_connector = radeon_connector->con_priv; - - if (!radeon_encoder->enc_priv) - return; - - dig = radeon_encoder->enc_priv; - memset(&args, 0, sizeof(args)); + if (ASIC_IS_DCE4(rdev)) + index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); + else { if (dig->dig_encoder) index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); else index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + } num = dig->dig_encoder + 1; atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); - args.ucAction = action; - args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v1.ucAction = action; + args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); - if (ASIC_IS_DCE32(rdev)) { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; - break; - } + if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { + if (dig_connector->dp_clock == 270000) + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; + args.v1.ucLaneNum = dig_connector->dp_lane_count; + } else if (radeon_encoder->pixel_clock > 165000) + args.v1.ucLaneNum = 8; + else + args.v1.ucLaneNum = 4; + + if (ASIC_IS_DCE4(rdev)) { + args.v3.acConfig.ucDigSel = dig->dig_encoder; + args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; } else { switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; break; } - } - - args.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { - if (dig_connector->dp_clock == 270000) - args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; - args.ucLaneNum = dig_connector->dp_lane_count; - } else if (radeon_encoder->pixel_clock > 165000) - args.ucLaneNum = 8; - else - args.ucLaneNum = 4; - if (dig_connector->linkb) - args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; else - args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; + } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -753,6 +770,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) union dig_transmitter_control { DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; + DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; }; void @@ -761,37 +779,29 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_connector_atom_dig *dig_connector = + radeon_get_atom_connector_priv_from_encoder(encoder); + struct drm_connector *connector; + struct radeon_connector *radeon_connector; union dig_transmitter_control args; int index = 0, num = 0; uint8_t frev, crev; - struct radeon_encoder_atom_dig *dig; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; bool is_dp = false; + int pll_id = 0; + + if (!dig || !dig_connector) + return; connector = radeon_get_connector_for_encoder(encoder); - if (!connector) - return; - radeon_connector = to_radeon_connector(connector); - if (!radeon_encoder->enc_priv) - return; - - dig = radeon_encoder->enc_priv; - - if (!radeon_connector->con_priv) - return; - - dig_connector = radeon_connector->con_priv; - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) is_dp = true; memset(&args, 0, sizeof(args)); - if (ASIC_IS_DCE32(rdev)) + if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); else { switch (radeon_encoder->encoder_id) { @@ -821,7 +831,54 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); } - if (ASIC_IS_DCE32(rdev)) { + if (ASIC_IS_DCE4(rdev)) { + if (is_dp) + args.v3.ucLaneNum = dig_connector->dp_lane_count; + else if (radeon_encoder->pixel_clock > 165000) + args.v3.ucLaneNum = 8; + else + args.v3.ucLaneNum = 4; + + if (dig_connector->linkb) { + args.v3.acConfig.ucLinkSel = 1; + args.v3.acConfig.ucEncoderSel = 1; + } + + /* Select the PLL for the PHY + * DP PHY should be clocked from external src if there is + * one. + */ + if (encoder->crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); + pll_id = radeon_crtc->pll_id; + } + if (is_dp && rdev->clock.dp_extclk) + args.v3.acConfig.ucRefClkSource = 2; /* external src */ + else + args.v3.acConfig.ucRefClkSource = pll_id; + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + args.v3.acConfig.ucTransmitterSel = 0; + num = 0; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + args.v3.acConfig.ucTransmitterSel = 1; + num = 1; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + args.v3.acConfig.ucTransmitterSel = 2; + num = 2; + break; + } + + if (is_dp) + args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ + else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { + if (dig->coherent_mode) + args.v3.acConfig.fCoherentMode = 1; + } + } else if (ASIC_IS_DCE32(rdev)) { if (dig->dig_encoder == 1) args.v2.acConfig.ucEncoderSel = 1; if (dig_connector->linkb) @@ -849,7 +906,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t args.v2.acConfig.fCoherentMode = 1; } } else { - args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; if (dig->dig_encoder) @@ -1024,9 +1080,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } -union crtc_sourc_param { +union crtc_source_param { SELECT_CRTC_SOURCE_PS_ALLOCATION v1; SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; }; @@ -1038,7 +1097,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - union crtc_sourc_param args; + union crtc_source_param args; int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); uint8_t frev, crev; struct radeon_encoder_atom_dig *dig; @@ -1107,10 +1166,26 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: dig = radeon_encoder->enc_priv; - if (dig->dig_encoder) + switch (dig->dig_encoder) { + case 0: + args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; + break; + case 1: args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; - else - args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; + break; + case 2: + args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; + break; + case 3: + args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; + break; + case 4: + args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; + break; + case 5: + args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; + break; + } break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; @@ -1167,6 +1242,7 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, } /* set scaler clears this on some chips */ + /* XXX check DCE4 */ if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, @@ -1183,6 +1259,33 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) struct drm_encoder *test_encoder; struct radeon_encoder_atom_dig *dig; uint32_t dig_enc_in_use = 0; + + if (ASIC_IS_DCE4(rdev)) { + struct radeon_connector_atom_dig *dig_connector = + radeon_get_atom_connector_priv_from_encoder(encoder); + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + if (dig_connector->linkb) + return 1; + else + return 0; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + if (dig_connector->linkb) + return 3; + else + return 2; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + if (dig_connector->linkb) + return 5; + else + return 4; + break; + } + } + /* on DCE32 and encoder can driver any block so just crtc id */ if (ASIC_IS_DCE32(rdev)) { return radeon_crtc->crtc_id; @@ -1254,6 +1357,16 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + if (ASIC_IS_DCE4(rdev)) { + /* disable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + /* setup and enable the encoder */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); + + /* init and enable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + } else { /* disable the encoder and transmitter */ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); atombios_dig_encoder_setup(encoder, ATOM_DISABLE); @@ -1263,6 +1376,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + } break; case ENCODER_OBJECT_ID_INTERNAL_DDI: atombios_ddia_setup(encoder, ATOM_ENABLE); @@ -1282,6 +1396,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } atombios_apply_encoder_quirks(encoder, adjusted_mode); + /* XXX */ + if (!ASIC_IS_DCE4(rdev)) r600_hdmi_setmode(encoder, adjusted_mode); } @@ -1480,10 +1596,18 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su return; encoder = &radeon_encoder->base; - if (rdev->flags & RADEON_SINGLE_CRTC) + switch (rdev->num_crtc) { + case 1: encoder->possible_crtcs = 0x1; - else + break; + case 2: + default: encoder->possible_crtcs = 0x3; + break; + case 6: + encoder->possible_crtcs = 0x3f; + break; + } radeon_encoder->enc_priv = NULL; diff --git a/drivers/video/drm/radeon/radeon_family.h b/drivers/video/drm/radeon/radeon_family.h index b635484320..32b78c74eb 100644 --- a/drivers/video/drm/radeon/radeon_family.h +++ b/drivers/video/drm/radeon/radeon_family.h @@ -75,6 +75,11 @@ enum radeon_family { CHIP_RV730, CHIP_RV710, CHIP_RV740, + CHIP_CEDAR, + CHIP_REDWOOD, + CHIP_JUNIPER, + CHIP_CYPRESS, + CHIP_HEMLOCK, CHIP_LAST, }; diff --git a/drivers/video/drm/radeon/radeon_fb.c b/drivers/video/drm/radeon/radeon_fb.c index b06a08de1e..d3476d9206 100644 --- a/drivers/video/drm/radeon/radeon_fb.c +++ b/drivers/video/drm/radeon/radeon_fb.c @@ -147,14 +147,13 @@ int radeonfb_create(struct drm_device *dev, struct drm_mode_fb_cmd mode_cmd; struct drm_gem_object *gobj = NULL; struct radeon_bo *rbo = NULL; - // struct device *device = &rdev->pdev->dev; + struct device *device = &rdev->pdev->dev; int size, aligned_size, ret; u64 fb_gpuaddr; void *fbptr = NULL; unsigned long tmp; bool fb_tiled = false; /* useful for testing */ u32 tiling_flags = 0; - int crtc_count; mode_cmd.width = surface_width; mode_cmd.height = surface_height; @@ -235,7 +234,7 @@ int radeonfb_create(struct drm_device *dev, rdev->fbdev_rfb = rfb; rdev->fbdev_rbo = rbo; - info = framebuffer_alloc(sizeof(struct radeon_fb_device), NULL); + info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); if (info == NULL) { ret = -ENOMEM; goto out_unref; @@ -245,11 +244,7 @@ int radeonfb_create(struct drm_device *dev, rfbdev = info->par; rfbdev->helper.funcs = &radeon_fb_helper_funcs; rfbdev->helper.dev = dev; - if (rdev->flags & RADEON_SINGLE_CRTC) - crtc_count = 1; - else - crtc_count = 2; - ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, crtc_count, + ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, rdev->num_crtc, RADEONFB_CONN_LIMIT); if (ret) goto out_unref; @@ -262,7 +257,7 @@ int radeonfb_create(struct drm_device *dev, info->flags = FBINFO_DEFAULT; info->fbops = &radeonfb_ops; - tmp = fb_gpuaddr - rdev->mc.vram_location; + tmp = fb_gpuaddr - rdev->mc.vram_start; info->fix.smem_start = rdev->mc.aper_base + tmp; info->fix.smem_len = size; info->screen_base = fbptr; @@ -362,6 +357,4 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) return 0; } EXPORT_SYMBOL(radeonfb_remove); - - - +MODULE_LICENSE("GPL"); diff --git a/drivers/video/drm/radeon/radeon_gart.c b/drivers/video/drm/radeon/radeon_gart.c index 0eabffa68e..ea20eeb1be 100644 --- a/drivers/video/drm/radeon/radeon_gart.c +++ b/drivers/video/drm/radeon/radeon_gart.c @@ -139,6 +139,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, unsigned t; unsigned p; int i, j; + u64 page_base; if (!rdev->gart.ready) { WARN(1, "trying to unbind memory to unitialized GART !\n"); @@ -151,9 +152,11 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, // pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], // PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); rdev->gart.pages[p] = NULL; - rdev->gart.pages_addr[p] = 0; + rdev->gart.pages_addr[p] = rdev->dummy_page.addr; + page_base = rdev->gart.pages_addr[p]; for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { - radeon_gart_set_page(rdev, t, 0); + radeon_gart_set_page(rdev, t, page_base); + page_base += RADEON_GPU_PAGE_SIZE; } } } @@ -187,11 +190,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, rdev->gart.pages_addr[p] = pagelist[i] & ~4095; - //if (pci_dma_mapping_error(rdev->pdev, rdev->gart.pages_addr[p])) { - // /* FIXME: failed to map page (return -ENOMEM?) */ - // radeon_gart_unbind(rdev, offset, pages); - // return -ENOMEM; - //} + rdev->gart.pages[p] = pagelist[i]; page_base = rdev->gart.pages_addr[p]; for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { @@ -204,8 +203,26 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, return 0; } +void radeon_gart_restore(struct radeon_device *rdev) +{ + int i, j, t; + u64 page_base; + + for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { + page_base = rdev->gart.pages_addr[i]; + for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { + radeon_gart_set_page(rdev, t, page_base); + page_base += RADEON_GPU_PAGE_SIZE; + } + } + mb(); + radeon_gart_tlb_flush(rdev); +} + int radeon_gart_init(struct radeon_device *rdev) { + int r, i; + if (rdev->gart.pages) { return 0; } @@ -214,6 +231,9 @@ int radeon_gart_init(struct radeon_device *rdev) DRM_ERROR("Page size is smaller than GPU page size!\n"); return -EINVAL; } + r = radeon_dummy_page_init(rdev); + if (r) + return r; /* Compute table size */ rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE; @@ -232,6 +252,10 @@ int radeon_gart_init(struct radeon_device *rdev) radeon_gart_fini(rdev); return -ENOMEM; } + /* set GART entry to point to the dummy page by default */ + for (i = 0; i < rdev->gart.num_cpu_pages; i++) { + rdev->gart.pages_addr[i] = rdev->dummy_page.addr; + } return 0; } diff --git a/drivers/video/drm/radeon/radeon_i2c.c b/drivers/video/drm/radeon/radeon_i2c.c index b987b568db..692e7ef983 100644 --- a/drivers/video/drm/radeon/radeon_i2c.c +++ b/drivers/video/drm/radeon/radeon_i2c.c @@ -26,6 +26,7 @@ #include "drmP.h" #include "radeon_drm.h" #include "radeon.h" +#include "atom.h" /** * radeon_ddc_probe @@ -59,7 +60,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) } -void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) +static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) { struct radeon_device *rdev = i2c->dev->dev_private; struct radeon_i2c_bus_rec *rec = &i2c->rec; @@ -71,7 +72,18 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) */ if (rec->hw_capable) { if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { - if (rec->a_clk_reg == RADEON_GPIO_MONID) { + u32 reg; + + if (rdev->family >= CHIP_RV350) + reg = RADEON_GPIO_MONID; + else if ((rdev->family == CHIP_R300) || + (rdev->family == CHIP_R350)) + reg = RADEON_GPIO_DVI_DDC; + else + reg = RADEON_GPIO_CRT2_DDC; + + mutex_lock(&rdev->dc_hw_i2c_mutex); + if (rec->a_clk_reg == reg) { WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); } else { @@ -168,6 +180,692 @@ static void set_data(void *i2c_priv, int data) WREG32(rec->en_data_reg, val); } +static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) +{ + struct radeon_pll *spll = &rdev->clock.spll; + u32 sclk = radeon_get_engine_clock(rdev); + u32 prescale = 0; + u32 n, m; + u8 loop; + int i2c_clock; + + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + case CHIP_R200: + case CHIP_RV250: + case CHIP_RS300: + case CHIP_RV280: + case CHIP_R300: + case CHIP_R350: + case CHIP_RV350: + n = (spll->reference_freq) / (4 * 6); + for (loop = 1; loop < 255; loop++) { + if ((loop * (loop - 1)) > n) + break; + } + m = loop - 1; + prescale = m | (loop << 8); + break; + case CHIP_RV380: + case CHIP_RS400: + case CHIP_RS480: + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: + sclk = radeon_get_engine_clock(rdev); + prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + break; + case CHIP_RS600: + case CHIP_RS690: + case CHIP_RS740: + /* todo */ + break; + case CHIP_RV515: + case CHIP_R520: + case CHIP_RV530: + case CHIP_RV560: + case CHIP_RV570: + case CHIP_R580: + i2c_clock = 50; + sclk = radeon_get_engine_clock(rdev); + if (rdev->family == CHIP_R520) + prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); + else + prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + break; + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV670: + /* todo */ + break; + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RS780: + case CHIP_RS880: + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + /* todo */ + break; + case CHIP_CEDAR: + case CHIP_REDWOOD: + case CHIP_JUNIPER: + case CHIP_CYPRESS: + case CHIP_HEMLOCK: + /* todo */ + break; + default: + DRM_ERROR("i2c: unhandled radeon chip\n"); + break; + } + return prescale; +} + + +/* hw i2c engine for r1xx-4xx hardware + * hw can buffer up to 15 bytes + */ +static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct radeon_device *rdev = i2c->dev->dev_private; + struct radeon_i2c_bus_rec *rec = &i2c->rec; + struct i2c_msg *p; + int i, j, k, ret = num; + u32 prescale; + u32 i2c_cntl_0, i2c_cntl_1, i2c_data; + u32 tmp, reg; + + mutex_lock(&rdev->dc_hw_i2c_mutex); + /* take the pm lock since we need a constant sclk */ + mutex_lock(&rdev->pm.mutex); + + prescale = radeon_get_i2c_prescale(rdev); + + reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | + RADEON_I2C_START | + RADEON_I2C_STOP | + RADEON_I2C_GO); + + if (rdev->is_atom_bios) { + tmp = RREG32(RADEON_BIOS_6_SCRATCH); + WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); + } + + if (rec->mm_i2c) { + i2c_cntl_0 = RADEON_I2C_CNTL_0; + i2c_cntl_1 = RADEON_I2C_CNTL_1; + i2c_data = RADEON_I2C_DATA; + } else { + i2c_cntl_0 = RADEON_DVI_I2C_CNTL_0; + i2c_cntl_1 = RADEON_DVI_I2C_CNTL_1; + i2c_data = RADEON_DVI_I2C_DATA; + + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + case CHIP_RS300: + switch (rec->mask_clk_reg) { + case RADEON_GPIO_DVI_DDC: + /* no gpio select bit */ + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + break; + case CHIP_R200: + /* only bit 4 on r200 */ + switch (rec->mask_clk_reg) { + case RADEON_GPIO_DVI_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); + break; + case RADEON_GPIO_MONID: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + break; + case CHIP_RV250: + case CHIP_RV280: + /* bits 3 and 4 */ + switch (rec->mask_clk_reg) { + case RADEON_GPIO_DVI_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); + break; + case RADEON_GPIO_VGA_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); + break; + case RADEON_GPIO_CRT2_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + break; + case CHIP_R300: + case CHIP_R350: + /* only bit 4 on r300/r350 */ + switch (rec->mask_clk_reg) { + case RADEON_GPIO_VGA_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); + break; + case RADEON_GPIO_DVI_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + break; + case CHIP_RV350: + case CHIP_RV380: + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: + case CHIP_RS400: + case CHIP_RS480: + /* bits 3 and 4 */ + switch (rec->mask_clk_reg) { + case RADEON_GPIO_VGA_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); + break; + case RADEON_GPIO_DVI_DDC: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); + break; + case RADEON_GPIO_MONID: + reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + break; + default: + DRM_ERROR("unsupported asic\n"); + ret = -EINVAL; + goto done; + break; + } + } + + /* check for bus probe */ + p = &msgs[0]; + if ((num == 1) && (p->len == 0)) { + WREG32(i2c_cntl_0, (RADEON_I2C_DONE | + RADEON_I2C_NACK | + RADEON_I2C_HALT | + RADEON_I2C_SOFT_RST)); + WREG32(i2c_data, (p->addr << 1) & 0xff); + WREG32(i2c_data, 0); + WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | + (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | + RADEON_I2C_EN | + (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); + WREG32(i2c_cntl_0, reg); + for (k = 0; k < 32; k++) { + udelay(10); + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_GO) + continue; + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_DONE) + break; + else { + DRM_DEBUG("i2c write error 0x%08x\n", tmp); + WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); + ret = -EIO; + goto done; + } + } + goto done; + } + + for (i = 0; i < num; i++) { + p = &msgs[i]; + for (j = 0; j < p->len; j++) { + if (p->flags & I2C_M_RD) { + WREG32(i2c_cntl_0, (RADEON_I2C_DONE | + RADEON_I2C_NACK | + RADEON_I2C_HALT | + RADEON_I2C_SOFT_RST)); + WREG32(i2c_data, ((p->addr << 1) & 0xff) | 0x1); + WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | + (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | + RADEON_I2C_EN | + (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); + WREG32(i2c_cntl_0, reg | RADEON_I2C_RECEIVE); + for (k = 0; k < 32; k++) { + udelay(10); + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_GO) + continue; + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_DONE) + break; + else { + DRM_DEBUG("i2c read error 0x%08x\n", tmp); + WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); + ret = -EIO; + goto done; + } + } + p->buf[j] = RREG32(i2c_data) & 0xff; + } else { + WREG32(i2c_cntl_0, (RADEON_I2C_DONE | + RADEON_I2C_NACK | + RADEON_I2C_HALT | + RADEON_I2C_SOFT_RST)); + WREG32(i2c_data, (p->addr << 1) & 0xff); + WREG32(i2c_data, p->buf[j]); + WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | + (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | + RADEON_I2C_EN | + (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); + WREG32(i2c_cntl_0, reg); + for (k = 0; k < 32; k++) { + udelay(10); + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_GO) + continue; + tmp = RREG32(i2c_cntl_0); + if (tmp & RADEON_I2C_DONE) + break; + else { + DRM_DEBUG("i2c write error 0x%08x\n", tmp); + WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); + ret = -EIO; + goto done; + } + } + } + } + } + +done: + WREG32(i2c_cntl_0, 0); + WREG32(i2c_cntl_1, 0); + WREG32(i2c_cntl_0, (RADEON_I2C_DONE | + RADEON_I2C_NACK | + RADEON_I2C_HALT | + RADEON_I2C_SOFT_RST)); + + if (rdev->is_atom_bios) { + tmp = RREG32(RADEON_BIOS_6_SCRATCH); + tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; + WREG32(RADEON_BIOS_6_SCRATCH, tmp); + } + + mutex_unlock(&rdev->pm.mutex); + mutex_unlock(&rdev->dc_hw_i2c_mutex); + + return ret; +} + +/* hw i2c engine for r5xx hardware + * hw can buffer up to 15 bytes + */ +static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct radeon_device *rdev = i2c->dev->dev_private; + struct radeon_i2c_bus_rec *rec = &i2c->rec; + struct i2c_msg *p; + int i, j, remaining, current_count, buffer_offset, ret = num; + u32 prescale; + u32 tmp, reg; + u32 saved1, saved2; + + mutex_lock(&rdev->dc_hw_i2c_mutex); + /* take the pm lock since we need a constant sclk */ + mutex_lock(&rdev->pm.mutex); + + prescale = radeon_get_i2c_prescale(rdev); + + /* clear gpio mask bits */ + tmp = RREG32(rec->mask_clk_reg); + tmp &= ~rec->mask_clk_mask; + WREG32(rec->mask_clk_reg, tmp); + tmp = RREG32(rec->mask_clk_reg); + + tmp = RREG32(rec->mask_data_reg); + tmp &= ~rec->mask_data_mask; + WREG32(rec->mask_data_reg, tmp); + tmp = RREG32(rec->mask_data_reg); + + /* clear pin values */ + tmp = RREG32(rec->a_clk_reg); + tmp &= ~rec->a_clk_mask; + WREG32(rec->a_clk_reg, tmp); + tmp = RREG32(rec->a_clk_reg); + + tmp = RREG32(rec->a_data_reg); + tmp &= ~rec->a_data_mask; + WREG32(rec->a_data_reg, tmp); + tmp = RREG32(rec->a_data_reg); + + /* set the pins to input */ + tmp = RREG32(rec->en_clk_reg); + tmp &= ~rec->en_clk_mask; + WREG32(rec->en_clk_reg, tmp); + tmp = RREG32(rec->en_clk_reg); + + tmp = RREG32(rec->en_data_reg); + tmp &= ~rec->en_data_mask; + WREG32(rec->en_data_reg, tmp); + tmp = RREG32(rec->en_data_reg); + + /* */ + tmp = RREG32(RADEON_BIOS_6_SCRATCH); + WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); + saved1 = RREG32(AVIVO_DC_I2C_CONTROL1); + saved2 = RREG32(0x494); + WREG32(0x494, saved2 | 0x1); + + WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C); + for (i = 0; i < 50; i++) { + udelay(1); + if (RREG32(AVIVO_DC_I2C_ARBITRATION) & AVIVO_DC_I2C_SW_CAN_USE_I2C) + break; + } + if (i == 50) { + DRM_ERROR("failed to get i2c bus\n"); + ret = -EBUSY; + goto done; + } + + reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN; + switch (rec->mask_clk_reg) { + case AVIVO_DC_GPIO_DDC1_MASK: + reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC1); + break; + case AVIVO_DC_GPIO_DDC2_MASK: + reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC2); + break; + case AVIVO_DC_GPIO_DDC3_MASK: + reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC3); + break; + default: + DRM_ERROR("gpio not supported with hw i2c\n"); + ret = -EINVAL; + goto done; + } + + /* check for bus probe */ + p = &msgs[0]; + if ((num == 1) && (p->len == 0)) { + WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | + AVIVO_DC_I2C_NACK | + AVIVO_DC_I2C_HALT)); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); + udelay(1); + WREG32(AVIVO_DC_I2C_RESET, 0); + + WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); + WREG32(AVIVO_DC_I2C_DATA, 0); + + WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); + WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | + AVIVO_DC_I2C_DATA_COUNT(1) | + (prescale << 16))); + WREG32(AVIVO_DC_I2C_CONTROL1, reg); + WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); + for (j = 0; j < 200; j++) { + udelay(50); + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_GO) + continue; + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_DONE) + break; + else { + DRM_DEBUG("i2c write error 0x%08x\n", tmp); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); + ret = -EIO; + goto done; + } + } + goto done; + } + + for (i = 0; i < num; i++) { + p = &msgs[i]; + remaining = p->len; + buffer_offset = 0; + if (p->flags & I2C_M_RD) { + while (remaining) { + if (remaining > 15) + current_count = 15; + else + current_count = remaining; + WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | + AVIVO_DC_I2C_NACK | + AVIVO_DC_I2C_HALT)); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); + udelay(1); + WREG32(AVIVO_DC_I2C_RESET, 0); + + WREG32(AVIVO_DC_I2C_DATA, ((p->addr << 1) & 0xff) | 0x1); + WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); + WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | + AVIVO_DC_I2C_DATA_COUNT(current_count) | + (prescale << 16))); + WREG32(AVIVO_DC_I2C_CONTROL1, reg | AVIVO_DC_I2C_RECEIVE); + WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); + for (j = 0; j < 200; j++) { + udelay(50); + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_GO) + continue; + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_DONE) + break; + else { + DRM_DEBUG("i2c read error 0x%08x\n", tmp); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); + ret = -EIO; + goto done; + } + } + for (j = 0; j < current_count; j++) + p->buf[buffer_offset + j] = RREG32(AVIVO_DC_I2C_DATA) & 0xff; + remaining -= current_count; + buffer_offset += current_count; + } + } else { + while (remaining) { + if (remaining > 15) + current_count = 15; + else + current_count = remaining; + WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | + AVIVO_DC_I2C_NACK | + AVIVO_DC_I2C_HALT)); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); + udelay(1); + WREG32(AVIVO_DC_I2C_RESET, 0); + + WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); + for (j = 0; j < current_count; j++) + WREG32(AVIVO_DC_I2C_DATA, p->buf[buffer_offset + j]); + + WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); + WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | + AVIVO_DC_I2C_DATA_COUNT(current_count) | + (prescale << 16))); + WREG32(AVIVO_DC_I2C_CONTROL1, reg); + WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); + for (j = 0; j < 200; j++) { + udelay(50); + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_GO) + continue; + tmp = RREG32(AVIVO_DC_I2C_STATUS1); + if (tmp & AVIVO_DC_I2C_DONE) + break; + else { + DRM_DEBUG("i2c write error 0x%08x\n", tmp); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); + ret = -EIO; + goto done; + } + } + remaining -= current_count; + buffer_offset += current_count; + } + } + } + +done: + WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | + AVIVO_DC_I2C_NACK | + AVIVO_DC_I2C_HALT)); + WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); + udelay(1); + WREG32(AVIVO_DC_I2C_RESET, 0); + + WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_DONE_USING_I2C); + WREG32(AVIVO_DC_I2C_CONTROL1, saved1); + WREG32(0x494, saved2); + tmp = RREG32(RADEON_BIOS_6_SCRATCH); + tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; + WREG32(RADEON_BIOS_6_SCRATCH, tmp); + + mutex_unlock(&rdev->pm.mutex); + mutex_unlock(&rdev->dc_hw_i2c_mutex); + + return ret; +} + +static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + int ret; + + radeon_i2c_do_lock(i2c, 1); + ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num); + radeon_i2c_do_lock(i2c, 0); + + return ret; +} + +static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct radeon_device *rdev = i2c->dev->dev_private; + struct radeon_i2c_bus_rec *rec = &i2c->rec; + int ret; + + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + case CHIP_R200: + case CHIP_RV250: + case CHIP_RS300: + case CHIP_RV280: + case CHIP_R300: + case CHIP_R350: + case CHIP_RV350: + case CHIP_RV380: + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: + case CHIP_RS400: + case CHIP_RS480: + if (rec->hw_capable) + ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); + else + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + case CHIP_RS600: + case CHIP_RS690: + case CHIP_RS740: + /* XXX fill in hw i2c implementation */ + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + case CHIP_RV515: + case CHIP_R520: + case CHIP_RV530: + case CHIP_RV560: + case CHIP_RV570: + case CHIP_R580: + if (rec->hw_capable) { + if (rec->mm_i2c) + ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); + else + ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); + } else + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV670: + /* XXX fill in hw i2c implementation */ + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RS780: + case CHIP_RS880: + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + /* XXX fill in hw i2c implementation */ + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + case CHIP_CEDAR: + case CHIP_REDWOOD: + case CHIP_JUNIPER: + case CHIP_CYPRESS: + case CHIP_HEMLOCK: + /* XXX fill in hw i2c implementation */ + ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); + break; + default: + DRM_ERROR("i2c: unhandled radeon chip\n"); + ret = -EIO; + break; + } + + return ret; +} + +static u32 radeon_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm radeon_i2c_algo = { + .master_xfer = radeon_i2c_xfer, + .functionality = radeon_i2c_func, +}; + struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, const char *name) @@ -179,23 +877,33 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, if (i2c == NULL) return NULL; - i2c->dev = dev; - i2c->adapter.algo_data = &i2c->algo.bit; - i2c->algo.bit.setsda = set_data; - i2c->algo.bit.setscl = set_clock; - i2c->algo.bit.getsda = get_data; - i2c->algo.bit.getscl = get_clock; - i2c->algo.bit.udelay = 20; + /* set the internal bit adapter */ +// i2c->algo.radeon.bit_adapter.owner = THIS_MODULE; + i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c); +// sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name); + i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data; + i2c->algo.radeon.bit_data.setsda = set_data; + i2c->algo.radeon.bit_data.setscl = set_clock; + i2c->algo.radeon.bit_data.getsda = get_data; + i2c->algo.radeon.bit_data.getscl = get_clock; + i2c->algo.radeon.bit_data.udelay = 20; /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always * make this, 2 jiffies is a lot more reliable */ - i2c->algo.bit.timeout = 2; - i2c->algo.bit.data = i2c; - i2c->rec = *rec; - ret = i2c_bit_add_bus(&i2c->adapter); + i2c->algo.radeon.bit_data.timeout = 2; + i2c->algo.radeon.bit_data.data = i2c; + ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter); if (ret) { - DRM_INFO("Failed to register i2c %s\n", name); + DRM_ERROR("Failed to register internal bit i2c %s\n", name); goto out_free; } + /* set the radeon i2c adapter */ + i2c->dev = dev; + i2c->rec = *rec; +// i2c->adapter.owner = THIS_MODULE; + i2c_set_adapdata(&i2c->adapter, i2c); +// sprintf(i2c->adapter.name, "Radeon i2c %s", name); + i2c->adapter.algo_data = &i2c->algo.radeon; + i2c->adapter.algo = &radeon_i2c_algo; return i2c; out_free: @@ -218,6 +926,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; // i2c->adapter.owner = THIS_MODULE; i2c->dev = dev; + i2c_set_adapdata(&i2c->adapter, i2c); i2c->adapter.algo_data = &i2c->algo.dp; i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; i2c->algo.dp.address = 0; @@ -234,8 +943,14 @@ out_free: } - void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) +{ + if (!i2c) + return; + kfree(i2c); +} + +void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c) { if (!i2c) return; @@ -248,7 +963,7 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) return NULL; } -void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, +void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, u8 slave_addr, u8 addr, u8 *val) @@ -282,7 +997,7 @@ void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, } } -void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus, +void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, u8 slave_addr, u8 addr, u8 val) diff --git a/drivers/video/drm/radeon/radeon_legacy_crtc.c b/drivers/video/drm/radeon/radeon_legacy_crtc.c index 3310c0a536..ce76c96b55 100644 --- a/drivers/video/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/video/drm/radeon/radeon_legacy_crtc.c @@ -321,11 +321,13 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_DISP_REQ_EN_B)); WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); } + drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: + drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); if (radeon_crtc->crtc_id) WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); else { @@ -401,7 +403,7 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, /* if scanout was in GTT this really wouldn't work */ /* crtc offset is from display base addr not FB location */ - radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location; + radeon_crtc->legacy_display_base_addr = rdev->mc.vram_start; base -= radeon_crtc->legacy_display_base_addr; @@ -580,29 +582,6 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod ? RADEON_CRTC_V_SYNC_POL : 0)); - /* TODO -> Dell Server */ - if (0) { - uint32_t disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - uint32_t tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - uint32_t dac2_cntl = RREG32(RADEON_DAC_CNTL2); - uint32_t crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - - dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; - dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL; - - /* For CRT on DAC2, don't turn it on if BIOS didn't - enable it, even it's detected. - */ - disp_hw_debug |= RADEON_CRT2_DISP1_SEL; - tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16)); - tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16)); - - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - } - if (radeon_crtc->crtc_id) { uint32_t crtc2_gen_cntl; uint32_t disp2_merge_cntl; @@ -724,6 +703,10 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) pll = &rdev->clock.p1pll; pll->flags = RADEON_PLL_LEGACY; + if (radeon_new_pll == 1) + pll->algo = PLL_ALGO_NEW; + else + pll->algo = PLL_ALGO_LEGACY; if (mode->clock > 200000) /* range limits??? */ pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; diff --git a/drivers/video/drm/radeon/radeon_legacy_encoders.c b/drivers/video/drm/radeon/radeon_legacy_encoders.c index f8543c7d1c..bf50e5d1cd 100644 --- a/drivers/video/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/video/drm/radeon/radeon_legacy_encoders.c @@ -115,6 +115,9 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) @@ -214,6 +217,11 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + + /* adjust pm to upcoming mode change */ + radeon_pm_compute_clocks(rdev); /* set the active encoder to connector routing */ radeon_encoder_set_active_device(encoder); @@ -285,6 +293,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) @@ -470,6 +481,9 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) @@ -635,6 +649,9 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) @@ -842,6 +859,9 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); else radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); + + /* adjust pm to dpms change */ + radeon_pm_compute_clocks(rdev); } static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) diff --git a/drivers/video/drm/radeon/radeon_mode.h b/drivers/video/drm/radeon/radeon_mode.h index badbc730c3..c68ef8554a 100644 --- a/drivers/video/drm/radeon/radeon_mode.h +++ b/drivers/video/drm/radeon/radeon_mode.h @@ -83,6 +83,8 @@ struct radeon_i2c_bus_rec { bool valid; /* id used by atom */ uint8_t i2c_id; + /* id used by atom */ + uint8_t hpd_id; /* can be used with hw i2c engine */ bool hw_capable; /* uses multi-media i2c engine */ @@ -113,6 +115,7 @@ struct radeon_tmds_pll { #define RADEON_MAX_BIOS_CONNECTOR 16 +/* pll flags */ #define RADEON_PLL_USE_BIOS_DIVS (1 << 0) #define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) #define RADEON_PLL_USE_REF_DIV (1 << 2) @@ -127,6 +130,12 @@ struct radeon_tmds_pll { #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) #define RADEON_PLL_USE_POST_DIV (1 << 12) +/* pll algo */ +enum radeon_pll_algo { + PLL_ALGO_LEGACY, + PLL_ALGO_NEW +}; + struct radeon_pll { /* reference frequency */ uint32_t reference_freq; @@ -157,6 +166,13 @@ struct radeon_pll { /* pll id */ uint32_t id; + /* pll algo */ + enum radeon_pll_algo algo; +}; + +struct i2c_algo_radeon_data { + struct i2c_adapter bit_adapter; + struct i2c_algo_bit_data bit_data; }; struct radeon_i2c_chan { @@ -164,7 +180,7 @@ struct radeon_i2c_chan { struct drm_device *dev; union { struct i2c_algo_dp_aux_data dp; - struct i2c_algo_bit_data bit; + struct i2c_algo_radeon_data radeon; } algo; struct radeon_i2c_bus_rec rec; }; @@ -193,7 +209,7 @@ struct radeon_mode_info { struct card_info *atom_card_info; enum radeon_connector_table connector_table; bool mode_config_initialized; - struct radeon_crtc *crtcs[2]; + struct radeon_crtc *crtcs[6]; /* DVI-I properties */ struct drm_property *coherent_mode_property; /* DAC enable load detect */ @@ -202,7 +218,8 @@ struct radeon_mode_info { struct drm_property *tv_std_property; /* legacy TMDS PLL detect */ struct drm_property *tmds_pll_property; - + /* hardcoded DFP edid from BIOS */ + struct edid *bios_hardcoded_edid; }; #define MAX_H_CODE_TIMING_LEN 32 @@ -237,6 +254,7 @@ struct radeon_crtc { fixed20_12 vsc; fixed20_12 hsc; struct drm_display_mode native_mode; + int pll_id; }; struct radeon_encoder_primary_dac { @@ -303,6 +321,7 @@ struct radeon_encoder_atom_dig { /* atom lvds */ uint32_t lvds_misc; uint16_t panel_pwr_delay; + enum radeon_pll_algo pll_algo; struct radeon_atom_ss *ss; /* panel mode */ struct drm_display_mode native_mode; @@ -398,6 +417,7 @@ extern void dp_link_train(struct drm_encoder *encoder, struct drm_connector *connector); extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); +extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action); extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set); @@ -411,11 +431,12 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, const char *name); extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); -extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, +extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c); +extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, u8 slave_addr, u8 addr, u8 *val); -extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c, +extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 slave_addr, u8 addr, u8 val); @@ -432,14 +453,6 @@ extern void radeon_compute_pll(struct radeon_pll *pll, uint32_t *ref_div_p, uint32_t *post_div_p); -extern void radeon_compute_pll_avivo(struct radeon_pll *pll, - uint64_t freq, - uint32_t *dot_clock_p, - uint32_t *fb_div_p, - uint32_t *frac_fb_div_p, - uint32_t *ref_div_p, - uint32_t *post_div_p); - extern void radeon_setup_encoder_clones(struct drm_device *dev); struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); @@ -473,6 +486,9 @@ extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); +extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); +extern struct edid * +radeon_combios_get_hardcoded_edid(struct radeon_device *rdev); extern bool radeon_atom_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev); extern struct radeon_encoder_atom_dig * @@ -531,7 +547,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev, struct radeon_crtc *radeon_crtc); void radeon_legacy_init_crtc(struct drm_device *dev, struct radeon_crtc *radeon_crtc); -extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state); void radeon_get_clock_info(struct drm_device *dev); diff --git a/drivers/video/drm/radeon/radeon_object_kos.c b/drivers/video/drm/radeon/radeon_object_kos.c index f64de01ce7..1650edca27 100644 --- a/drivers/video/drm/radeon/radeon_object_kos.c +++ b/drivers/video/drm/radeon/radeon_object_kos.c @@ -179,7 +179,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) if(bo->domain & RADEON_GEM_DOMAIN_VRAM) { - bo->tbo.offset += (u64)bo->rdev->mc.vram_location; + bo->tbo.offset += (u64)bo->rdev->mc.vram_start; } else if (bo->domain & RADEON_GEM_DOMAIN_GTT) { @@ -191,7 +191,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) dbgprintf("pagelist %x\n", pagelist); radeon_gart_bind(bo->rdev, bo->tbo.offset, bo->tbo.vm_node->size, pagelist); - bo->tbo.offset += (u64)bo->rdev->mc.gtt_location; + bo->tbo.offset += (u64)bo->rdev->mc.gtt_start; } else { @@ -378,7 +378,7 @@ int radeon_fb_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, bo->tbo.vm_node = vm_node; bo->tbo.offset = bo->tbo.vm_node->start << PAGE_SHIFT; - bo->tbo.offset += (u64)bo->rdev->mc.vram_location; + bo->tbo.offset += (u64)bo->rdev->mc.vram_start; bo->kptr = (void*)0xFE000000; bo->pin_count = 1; diff --git a/drivers/video/drm/radeon/radeon_pm.c b/drivers/video/drm/radeon/radeon_pm.c index 8b7e5fb276..567d885471 100644 --- a/drivers/video/drm/radeon/radeon_pm.c +++ b/drivers/video/drm/radeon/radeon_pm.c @@ -18,21 +18,407 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Rafał Miłecki + * Alex Deucher */ #include "drmP.h" #include "radeon.h" +#include "avivod.h" -int radeon_debugfs_pm_init(struct radeon_device *rdev); +#define RADEON_IDLE_LOOP_MS 100 +#define RADEON_RECLOCK_DELAY_MS 200 +#define RADEON_WAIT_VBLANK_TIMEOUT 200 + +static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); +static void radeon_pm_set_clocks(struct radeon_device *rdev); +static void radeon_pm_idle_work_handler(struct work_struct *work); +static int radeon_debugfs_pm_init(struct radeon_device *rdev); + +static const char *pm_state_names[4] = { + "PM_STATE_DISABLED", + "PM_STATE_MINIMUM", + "PM_STATE_PAUSED", + "PM_STATE_ACTIVE" +}; + +static const char *pm_state_types[5] = { + "Default", + "Powersave", + "Battery", + "Balanced", + "Performance", +}; + +static void radeon_print_power_mode_info(struct radeon_device *rdev) +{ + int i, j; + bool is_default; + + DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states); + for (i = 0; i < rdev->pm.num_power_states; i++) { + if (rdev->pm.default_power_state == &rdev->pm.power_state[i]) + is_default = true; + else + is_default = false; + DRM_INFO("State %d %s %s\n", i, + pm_state_types[rdev->pm.power_state[i].type], + is_default ? "(default)" : ""); + if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) + DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes); + DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes); + for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) { + if (rdev->flags & RADEON_IS_IGP) + DRM_INFO("\t\t%d engine: %d\n", + j, + rdev->pm.power_state[i].clock_info[j].sclk * 10); + else + DRM_INFO("\t\t%d engine/memory: %d/%d\n", + j, + rdev->pm.power_state[i].clock_info[j].sclk * 10, + rdev->pm.power_state[i].clock_info[j].mclk * 10); + } + } +} + +static struct radeon_power_state * radeon_pick_power_state(struct radeon_device *rdev, + enum radeon_pm_state_type type) +{ + int i, j; + enum radeon_pm_state_type wanted_types[2]; + int wanted_count; + + switch (type) { + case POWER_STATE_TYPE_DEFAULT: + default: + return rdev->pm.default_power_state; + case POWER_STATE_TYPE_POWERSAVE: + if (rdev->flags & RADEON_IS_MOBILITY) { + wanted_types[0] = POWER_STATE_TYPE_POWERSAVE; + wanted_types[1] = POWER_STATE_TYPE_BATTERY; + wanted_count = 2; + } else { + wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; + wanted_count = 1; + } + break; + case POWER_STATE_TYPE_BATTERY: + if (rdev->flags & RADEON_IS_MOBILITY) { + wanted_types[0] = POWER_STATE_TYPE_BATTERY; + wanted_types[1] = POWER_STATE_TYPE_POWERSAVE; + wanted_count = 2; + } else { + wanted_types[0] = POWER_STATE_TYPE_PERFORMANCE; + wanted_count = 1; + } + break; + case POWER_STATE_TYPE_BALANCED: + case POWER_STATE_TYPE_PERFORMANCE: + wanted_types[0] = type; + wanted_count = 1; + break; + } + + for (i = 0; i < wanted_count; i++) { + for (j = 0; j < rdev->pm.num_power_states; j++) { + if (rdev->pm.power_state[j].type == wanted_types[i]) + return &rdev->pm.power_state[j]; + } + } + + return rdev->pm.default_power_state; +} + +static struct radeon_pm_clock_info * radeon_pick_clock_mode(struct radeon_device *rdev, + struct radeon_power_state *power_state, + enum radeon_pm_clock_mode_type type) +{ + switch (type) { + case POWER_MODE_TYPE_DEFAULT: + default: + return power_state->default_clock_mode; + case POWER_MODE_TYPE_LOW: + return &power_state->clock_info[0]; + case POWER_MODE_TYPE_MID: + if (power_state->num_clock_modes > 2) + return &power_state->clock_info[1]; + else + return &power_state->clock_info[0]; + break; + case POWER_MODE_TYPE_HIGH: + return &power_state->clock_info[power_state->num_clock_modes - 1]; + } + +} + +static void radeon_get_power_state(struct radeon_device *rdev, + enum radeon_pm_action action) +{ + switch (action) { + case PM_ACTION_MINIMUM: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_BATTERY); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_LOW); + break; + case PM_ACTION_DOWNCLOCK: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_POWERSAVE); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_MID); + break; + case PM_ACTION_UPCLOCK: + rdev->pm.requested_power_state = radeon_pick_power_state(rdev, POWER_STATE_TYPE_DEFAULT); + rdev->pm.requested_clock_mode = + radeon_pick_clock_mode(rdev, rdev->pm.requested_power_state, POWER_MODE_TYPE_HIGH); + break; + case PM_ACTION_NONE: + default: + DRM_ERROR("Requested mode for not defined action\n"); + return; + } + DRM_INFO("Requested: e: %d m: %d p: %d\n", + rdev->pm.requested_clock_mode->sclk, + rdev->pm.requested_clock_mode->mclk, + rdev->pm.requested_power_state->non_clock_info.pcie_lanes); +} + +static void radeon_set_power_state(struct radeon_device *rdev) +{ + /* if *_clock_mode are the same, *_power_state are as well */ + if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) + return; + + DRM_INFO("Setting: e: %d m: %d p: %d\n", + rdev->pm.requested_clock_mode->sclk, + rdev->pm.requested_clock_mode->mclk, + rdev->pm.requested_power_state->non_clock_info.pcie_lanes); + /* set pcie lanes */ + /* set voltage */ + /* set engine clock */ + radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); + /* set memory clock */ + + rdev->pm.current_power_state = rdev->pm.requested_power_state; + rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; +} int radeon_pm_init(struct radeon_device *rdev) { + rdev->pm.state = PM_STATE_DISABLED; + rdev->pm.planned_action = PM_ACTION_NONE; + rdev->pm.downclocked = false; + + if (rdev->bios) { + if (rdev->is_atom_bios) + radeon_atombios_get_power_modes(rdev); + else + radeon_combios_get_power_modes(rdev); + radeon_print_power_mode_info(rdev); + } + if (radeon_debugfs_pm_init(rdev)) { DRM_ERROR("Failed to register debugfs file for PM!\n"); } +// INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler); + + if (radeon_dynpm != -1 && radeon_dynpm) { + rdev->pm.state = PM_STATE_PAUSED; + DRM_INFO("radeon: dynamic power management enabled\n"); + } + + DRM_INFO("radeon: power management initialized\n"); + return 0; } +void radeon_pm_compute_clocks(struct radeon_device *rdev) +{ + struct drm_device *ddev = rdev->ddev; + struct drm_connector *connector; + struct radeon_crtc *radeon_crtc; + int count = 0; + + if (rdev->pm.state == PM_STATE_DISABLED) + return; + + mutex_lock(&rdev->pm.mutex); + + rdev->pm.active_crtcs = 0; + list_for_each_entry(connector, + &ddev->mode_config.connector_list, head) { + if (connector->encoder && + connector->dpms != DRM_MODE_DPMS_OFF) { + radeon_crtc = to_radeon_crtc(connector->encoder->crtc); + rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); + ++count; + } + } + + if (count > 1) { + if (rdev->pm.state == PM_STATE_ACTIVE) { + + rdev->pm.state = PM_STATE_PAUSED; + rdev->pm.planned_action = PM_ACTION_UPCLOCK; + if (rdev->pm.downclocked) + radeon_pm_set_clocks(rdev); + + DRM_DEBUG("radeon: dynamic power management deactivated\n"); + } + } else if (count == 1) { + /* TODO: Increase clocks if needed for current mode */ + + if (rdev->pm.state == PM_STATE_MINIMUM) { + rdev->pm.state = PM_STATE_ACTIVE; + rdev->pm.planned_action = PM_ACTION_UPCLOCK; + radeon_pm_set_clocks(rdev); + } + else if (rdev->pm.state == PM_STATE_PAUSED) { + rdev->pm.state = PM_STATE_ACTIVE; + DRM_DEBUG("radeon: dynamic power management activated\n"); + } + } + else { /* count == 0 */ + if (rdev->pm.state != PM_STATE_MINIMUM) { + rdev->pm.state = PM_STATE_MINIMUM; + rdev->pm.planned_action = PM_ACTION_MINIMUM; + radeon_pm_set_clocks(rdev); + } + } + + mutex_unlock(&rdev->pm.mutex); +} + +static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) +{ + u32 stat_crtc1 = 0, stat_crtc2 = 0; + bool in_vbl = true; + + if (ASIC_IS_AVIVO(rdev)) { + if (rdev->pm.active_crtcs & (1 << 0)) { + stat_crtc1 = RREG32(D1CRTC_STATUS); + if (!(stat_crtc1 & 1)) + in_vbl = false; + } + if (rdev->pm.active_crtcs & (1 << 1)) { + stat_crtc2 = RREG32(D2CRTC_STATUS); + if (!(stat_crtc2 & 1)) + in_vbl = false; + } + } + if (in_vbl == false) + DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1, + stat_crtc2, finish ? "exit" : "entry"); + return in_vbl; +} +static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) +{ + /*radeon_fence_wait_last(rdev);*/ + switch (rdev->pm.planned_action) { + case PM_ACTION_UPCLOCK: + rdev->pm.downclocked = false; + break; + case PM_ACTION_DOWNCLOCK: + rdev->pm.downclocked = true; + break; + case PM_ACTION_MINIMUM: + break; + case PM_ACTION_NONE: + DRM_ERROR("%s: PM_ACTION_NONE\n", __func__); + break; + } + + /* check if we are in vblank */ + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_power_state(rdev); + radeon_pm_debug_check_in_vbl(rdev, true); + rdev->pm.planned_action = PM_ACTION_NONE; +} + +static void radeon_pm_set_clocks(struct radeon_device *rdev) +{ + radeon_get_power_state(rdev, rdev->pm.planned_action); + mutex_lock(&rdev->cp.mutex); + + if (rdev->pm.active_crtcs & (1 << 0)) { + rdev->pm.req_vblank |= (1 << 0); +// drm_vblank_get(rdev->ddev, 0); + } + if (rdev->pm.active_crtcs & (1 << 1)) { + rdev->pm.req_vblank |= (1 << 1); +// drm_vblank_get(rdev->ddev, 1); + } + if (rdev->pm.active_crtcs) +// wait_event_interruptible_timeout( +// rdev->irq.vblank_queue, 0, +// msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); + if (rdev->pm.req_vblank & (1 << 0)) { + rdev->pm.req_vblank &= ~(1 << 0); +// drm_vblank_put(rdev->ddev, 0); + } + if (rdev->pm.req_vblank & (1 << 1)) { + rdev->pm.req_vblank &= ~(1 << 1); +// drm_vblank_put(rdev->ddev, 1); + } + + radeon_pm_set_clocks_locked(rdev); + mutex_unlock(&rdev->cp.mutex); +} + +#if 0 +static void radeon_pm_idle_work_handler(struct work_struct *work) +{ + struct radeon_device *rdev; + rdev = container_of(work, struct radeon_device, + pm.idle_work.work); + + mutex_lock(&rdev->pm.mutex); + if (rdev->pm.state == PM_STATE_ACTIVE) { + unsigned long irq_flags; + int not_processed = 0; + + read_lock_irqsave(&rdev->fence_drv.lock, irq_flags); + if (!list_empty(&rdev->fence_drv.emited)) { + struct list_head *ptr; + list_for_each(ptr, &rdev->fence_drv.emited) { + /* count up to 3, that's enought info */ + if (++not_processed >= 3) + break; + } + } + read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); + + if (not_processed >= 3) { /* should upclock */ + if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) { + rdev->pm.planned_action = PM_ACTION_NONE; + } else if (rdev->pm.planned_action == PM_ACTION_NONE && + rdev->pm.downclocked) { + rdev->pm.planned_action = + PM_ACTION_UPCLOCK; + rdev->pm.action_timeout = jiffies + + msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); + } + } else if (not_processed == 0) { /* should downclock */ + if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) { + rdev->pm.planned_action = PM_ACTION_NONE; + } else if (rdev->pm.planned_action == PM_ACTION_NONE && + !rdev->pm.downclocked) { + rdev->pm.planned_action = + PM_ACTION_DOWNCLOCK; + rdev->pm.action_timeout = jiffies + + msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); + } + } + + if (rdev->pm.planned_action != PM_ACTION_NONE && + jiffies > rdev->pm.action_timeout) { + radeon_pm_set_clocks(rdev); + } + } + mutex_unlock(&rdev->pm.mutex); + + queue_delayed_work(rdev->wq, &rdev->pm.idle_work, + msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); +} +#endif + /* * Debugfs info */ @@ -44,11 +430,14 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + seq_printf(m, "state: %s\n", pm_state_names[rdev->pm.state]); seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); if (rdev->asic->get_memory_clock) seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); + if (rdev->asic->get_pcie_lanes) + seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev)); return 0; } @@ -58,7 +447,7 @@ static struct drm_info_list radeon_pm_info_list[] = { }; #endif -int radeon_debugfs_pm_init(struct radeon_device *rdev) +static int radeon_debugfs_pm_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); diff --git a/drivers/video/drm/radeon/radeon_reg.h b/drivers/video/drm/radeon/radeon_reg.h index fe5a590ec2..1a0cb477ad 100644 --- a/drivers/video/drm/radeon/radeon_reg.h +++ b/drivers/video/drm/radeon/radeon_reg.h @@ -54,7 +54,7 @@ #include "r300_reg.h" #include "r500_reg.h" #include "r600_reg.h" - +#include "evergreen_reg.h" #define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_AGP_START_MASK 0x0000FFFF @@ -1060,32 +1060,38 @@ /* Multimedia I2C bus */ #define RADEON_I2C_CNTL_0 0x0090 -#define RADEON_I2C_DONE (1 << 0) -#define RADEON_I2C_NACK (1 << 1) -#define RADEON_I2C_HALT (1 << 2) -#define RADEON_I2C_SOFT_RST (1 << 5) -#define RADEON_I2C_DRIVE_EN (1 << 6) -#define RADEON_I2C_DRIVE_SEL (1 << 7) -#define RADEON_I2C_START (1 << 8) -#define RADEON_I2C_STOP (1 << 9) -#define RADEON_I2C_RECEIVE (1 << 10) -#define RADEON_I2C_ABORT (1 << 11) -#define RADEON_I2C_GO (1 << 12) -#define RADEON_I2C_PRESCALE_SHIFT 16 +# define RADEON_I2C_DONE (1 << 0) +# define RADEON_I2C_NACK (1 << 1) +# define RADEON_I2C_HALT (1 << 2) +# define RADEON_I2C_SOFT_RST (1 << 5) +# define RADEON_I2C_DRIVE_EN (1 << 6) +# define RADEON_I2C_DRIVE_SEL (1 << 7) +# define RADEON_I2C_START (1 << 8) +# define RADEON_I2C_STOP (1 << 9) +# define RADEON_I2C_RECEIVE (1 << 10) +# define RADEON_I2C_ABORT (1 << 11) +# define RADEON_I2C_GO (1 << 12) +# define RADEON_I2C_PRESCALE_SHIFT 16 #define RADEON_I2C_CNTL_1 0x0094 -#define RADEON_I2C_DATA_COUNT_SHIFT 0 -#define RADEON_I2C_ADDR_COUNT_SHIFT 4 -#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8 -#define RADEON_I2C_SEL (1 << 16) -#define RADEON_I2C_EN (1 << 17) -#define RADEON_I2C_TIME_LIMIT_SHIFT 24 +# define RADEON_I2C_DATA_COUNT_SHIFT 0 +# define RADEON_I2C_ADDR_COUNT_SHIFT 4 +# define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8 +# define RADEON_I2C_SEL (1 << 16) +# define RADEON_I2C_EN (1 << 17) +# define RADEON_I2C_TIME_LIMIT_SHIFT 24 #define RADEON_I2C_DATA 0x0098 #define RADEON_DVI_I2C_CNTL_0 0x02e0 # define R200_DVI_I2C_PIN_SEL(x) ((x) << 3) -# define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */ -# define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */ -# define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */ +# define R200_SEL_DDC1 0 /* depends on asic */ +# define R200_SEL_DDC2 1 /* depends on asic */ +# define R200_SEL_DDC3 2 /* depends on asic */ +# define RADEON_SW_WANTS_TO_USE_DVI_I2C (1 << 13) +# define RADEON_SW_CAN_USE_DVI_I2C (1 << 13) +# define RADEON_SW_DONE_USING_DVI_I2C (1 << 14) +# define RADEON_HW_NEEDS_DVI_I2C (1 << 14) +# define RADEON_ABORT_HW_DVI_I2C (1 << 15) +# define RADEON_HW_USING_DVI_I2C (1 << 15) #define RADEON_DVI_I2C_CNTL_1 0x02e4 #define RADEON_DVI_I2C_DATA 0x02e8 diff --git a/drivers/video/drm/radeon/radeon_ring.c b/drivers/video/drm/radeon/radeon_ring.c index 673111863d..2e7196826e 100644 --- a/drivers/video/drm/radeon/radeon_ring.c +++ b/drivers/video/drm/radeon/radeon_ring.c @@ -84,7 +84,7 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) mutex_unlock(&rdev->ib_pool.mutex); radeon_fence_unref(&fence); return r; - } + } mutex_lock(&rdev->ib_pool.mutex); } radeon_fence_unref(&nib->fence); @@ -146,6 +146,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) if (rdev->ib_pool.robj) return 0; + INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); /* Allocate 1M object buffer */ r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, true, RADEON_GEM_DOMAIN_GTT, @@ -278,8 +279,6 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) { int r; - ENTER(); - rdev->cp.ring_size = ring_size; /* Allocate ring buffer */ if (rdev->cp.ring_obj == NULL) { @@ -310,9 +309,6 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) } rdev->cp.ptr_mask = (rdev->cp.ring_size / 4) - 1; rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; - - LEAVE(); - return 0; } @@ -366,7 +362,12 @@ int radeon_debugfs_ib_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) unsigned i; + int r; + radeon_debugfs_ib_bogus_info_list[0].data = rdev; + r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1); + if (r) + return r; for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; diff --git a/drivers/video/drm/radeon/rdisplay.c b/drivers/video/drm/radeon/rdisplay.c index 3f0c8d04be..4764b5fc89 100644 --- a/drivers/video/drm/radeon/rdisplay.c +++ b/drivers/video/drm/radeon/rdisplay.c @@ -112,7 +112,7 @@ cursor_t* __stdcall select_cursor(cursor_t *cursor) if (ASIC_IS_AVIVO(rdev)) WREG32(AVIVO_D1CUR_SURFACE_ADDRESS, gpu_addr); else { - WREG32(RADEON_CUR_OFFSET, gpu_addr - rdev->mc.vram_location); + WREG32(RADEON_CUR_OFFSET, gpu_addr - rdev->mc.vram_start); } return old; @@ -189,7 +189,7 @@ void __stdcall move_cursor(cursor_t *cursor, int x, int y) /* offset is from DISP(2)_BASE_ADDRESS */ WREG32(RADEON_CUR_OFFSET, - (gpu_addr - rdev->mc.vram_location + (yorg * 256))); + (gpu_addr - rdev->mc.vram_start + (yorg * 256))); } radeon_lock_cursor(false); } @@ -296,7 +296,7 @@ int r100_2D_test(struct radeon_device *rdev) ENTER(); pitch = (1024*4)/64; - offset = rdev->mc.vram_location; + offset = rdev->mc.vram_start; r = radeon_ring_lock(rdev, 16); if (r) { @@ -2211,8 +2211,7 @@ int r600_2D_test(struct radeon_device *rdev) ENTER(); pitch = (1024*4)/64; - offset = rdev->mc.vram_location; - + offset = rdev->mc.vram_start; ps_size = R600_solid_ps(rdev, ps_shader); vs_size = R600_solid_vs(rdev, vs_shader); @@ -2355,7 +2354,7 @@ int r600_2D_test(struct radeon_device *rdev) set_render_target(rdev, COLOR_8_8_8_8, 1024, 768, /* FIXME */ - rdev->mc.vram_location); + rdev->mc.vram_start); set_scissors(rdev, 0, 0, 1024, 768); diff --git a/drivers/video/drm/radeon/rdisplay_kms.c b/drivers/video/drm/radeon/rdisplay_kms.c index db0ffa8628..8867d9bbc0 100644 --- a/drivers/video/drm/radeon/rdisplay_kms.c +++ b/drivers/video/drm/radeon/rdisplay_kms.c @@ -83,7 +83,7 @@ cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) if (ASIC_IS_AVIVO(rdev)) WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); else { - radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_location; + radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start; /* offset is from DISP(2)_BASE_ADDRESS */ WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); } @@ -175,7 +175,7 @@ void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) /* offset is from DISP(2)_BASE_ADDRESS */ WREG32(RADEON_CUR_OFFSET, - (gpu_addr - rdev->mc.vram_location + (yorg * 256))); + (gpu_addr - rdev->mc.vram_start + (yorg * 256))); } radeon_lock_cursor_kms(crtc, false); } diff --git a/drivers/video/drm/radeon/rs400.c b/drivers/video/drm/radeon/rs400.c index b8409a95ff..2616bf33da 100644 --- a/drivers/video/drm/radeon/rs400.c +++ b/drivers/video/drm/radeon/rs400.c @@ -113,6 +113,7 @@ int rs400_gart_enable(struct radeon_device *rdev) uint32_t size_reg; uint32_t tmp; + radeon_gart_restore(rdev); tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS; WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp); @@ -150,9 +151,8 @@ int rs400_gart_enable(struct radeon_device *rdev) WREG32(RADEON_AGP_BASE, 0xFFFFFFFF); WREG32(RS480_AGP_BASE_2, 0); } - tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; - tmp = REG_SET(RS690_MC_AGP_TOP, tmp >> 16); - tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_location >> 16); + tmp = REG_SET(RS690_MC_AGP_TOP, rdev->mc.gtt_end >> 16); + tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_start >> 16); if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { WREG32_MC(RS690_MCCFG_AGP_LOCATION, tmp); tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; @@ -251,14 +251,19 @@ void rs400_gpu_init(struct radeon_device *rdev) } } -void rs400_vram_info(struct radeon_device *rdev) +void rs400_mc_init(struct radeon_device *rdev) { + u64 base; + rs400_gart_adjust_size(rdev); + rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev); /* DDR for all card after R300 & IGP */ rdev->mc.vram_is_ddr = true; rdev->mc.vram_width = 128; - r100_vram_init_sizes(rdev); + base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + radeon_vram_location(rdev, &rdev->mc, base); + radeon_gtt_location(rdev, &rdev->mc); } uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) @@ -362,22 +367,6 @@ static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) #endif } -static int rs400_mc_init(struct radeon_device *rdev) -{ - int r; - u32 tmp; - - /* Setup GPU memory space */ - tmp = RREG32(R_00015C_NB_TOM); - rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; - rdev->mc.gtt_location = 0xFFFFFFFFUL; - r = radeon_mc_setup(rdev); - rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev); - if (r) - return r; - return 0; -} - void rs400_mc_program(struct radeon_device *rdev) { struct r100_mc_save save; @@ -472,12 +461,8 @@ int rs400_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - rs400_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = rs400_mc_init(rdev); - if (r) - return r; + /* initialize memory controller */ + rs400_mc_init(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); // if (r) diff --git a/drivers/video/drm/radeon/rs600.c b/drivers/video/drm/radeon/rs600.c index 1d333cc84f..8a282e9fc5 100644 --- a/drivers/video/drm/radeon/rs600.c +++ b/drivers/video/drm/radeon/rs600.c @@ -45,23 +45,6 @@ void rs600_gpu_init(struct radeon_device *rdev); int rs600_mc_wait_for_idle(struct radeon_device *rdev); -int rs600_mc_init(struct radeon_device *rdev) -{ - /* read back the MC value from the hw */ - int r; - u32 tmp; - - /* Setup GPU memory space */ - tmp = RREG32_MC(R_000004_MC_FB_LOCATION); - rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16; - rdev->mc.gtt_location = 0xffffffffUL; - r = radeon_mc_setup(rdev); - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - if (r) - return r; - return 0; -} - /* hpd for digital panel detect/disconnect */ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) { @@ -213,6 +196,7 @@ int rs600_gart_enable(struct radeon_device *rdev) r = radeon_gart_table_vram_pin(rdev); if (r) return r; + radeon_gart_restore(rdev); /* Enable bus master */ tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS; WREG32(R_00004C_BUS_CNTL, tmp); @@ -423,22 +407,22 @@ void rs600_gpu_init(struct radeon_device *rdev) dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); } -void rs600_vram_info(struct radeon_device *rdev) +void rs600_mc_init(struct radeon_device *rdev) { - rdev->mc.vram_is_ddr = true; - rdev->mc.vram_width = 128; - - rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); - rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + u64 base; rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); - - if (rdev->mc.mc_vram_size > rdev->mc.aper_size) - rdev->mc.mc_vram_size = rdev->mc.aper_size; - - if (rdev->mc.real_vram_size > rdev->mc.aper_size) - rdev->mc.real_vram_size = rdev->mc.aper_size; + rdev->mc.vram_is_ddr = true; + rdev->mc.vram_width = 128; + rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); + rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + base = RREG32_MC(R_000004_MC_FB_LOCATION); + base = G_000004_MC_FB_START(base) << 16; + radeon_vram_location(rdev, &rdev->mc, base); + radeon_gtt_location(rdev, &rdev->mc); } void rs600_bandwidth_update(struct radeon_device *rdev) @@ -571,12 +555,8 @@ int rs600_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - rs600_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = rs600_mc_init(rdev); - if (r) - return r; + /* initialize memory controller */ + rs600_mc_init(rdev); rs600_debugfs(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); diff --git a/drivers/video/drm/radeon/rs690.c b/drivers/video/drm/radeon/rs690.c index 1a306a02dd..9f34b93dd8 100644 --- a/drivers/video/drm/radeon/rs690.c +++ b/drivers/video/drm/radeon/rs690.c @@ -129,27 +129,21 @@ void rs690_pm_info(struct radeon_device *rdev) rdev->pm.sideport_bandwidth.full = rfixed_div(rdev->pm.sideport_bandwidth, tmp); } -void rs690_vram_info(struct radeon_device *rdev) +void rs690_mc_init(struct radeon_device *rdev) { fixed20_12 a; + u64 base; rs400_gart_adjust_size(rdev); - rdev->mc.vram_is_ddr = true; rdev->mc.vram_width = 128; - rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); - - if (rdev->mc.mc_vram_size > rdev->mc.aper_size) - rdev->mc.mc_vram_size = rdev->mc.aper_size; - - if (rdev->mc.real_vram_size > rdev->mc.aper_size) - rdev->mc.real_vram_size = rdev->mc.aper_size; - + rdev->mc.visible_vram_size = rdev->mc.aper_size; + base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); + base = G_000100_MC_FB_START(base) << 16; rs690_pm_info(rdev); /* FIXME: we should enforce default clock in case GPU is not in * default setup @@ -160,22 +154,9 @@ void rs690_vram_info(struct radeon_device *rdev) a.full = rfixed_const(16); /* core_bandwidth = sclk(Mhz) * 16 */ rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a); -} - -static int rs690_mc_init(struct radeon_device *rdev) -{ - int r; - u32 tmp; - - /* Setup GPU memory space */ - tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION); - rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16; - rdev->mc.gtt_location = 0xFFFFFFFFUL; - r = radeon_mc_setup(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - if (r) - return r; - return 0; + radeon_vram_location(rdev, &rdev->mc, base); + radeon_gtt_location(rdev, &rdev->mc); } void rs690_line_buffer_adjust(struct radeon_device *rdev, @@ -686,12 +667,8 @@ int rs690_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - rs690_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = rs690_mc_init(rdev); - if (r) - return r; + /* initialize memory controller */ + rs690_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); diff --git a/drivers/video/drm/radeon/rv515.c b/drivers/video/drm/radeon/rv515.c index 18ce2ce7a1..230a497be9 100644 --- a/drivers/video/drm/radeon/rv515.c +++ b/drivers/video/drm/radeon/rv515.c @@ -55,8 +55,6 @@ void rv515_ring_start(struct radeon_device *rdev) { int r; - ENTER(); - r = radeon_ring_lock(rdev, 64); if (r) { return; @@ -119,9 +117,6 @@ void rv515_ring_start(struct radeon_device *rdev) radeon_ring_write(rdev, PACKET0(0x20C8, 0)); radeon_ring_write(rdev, 0); radeon_ring_unlock_commit(rdev); - - LEAVE(); - } int rv515_mc_wait_for_idle(struct radeon_device *rdev) @@ -183,8 +178,6 @@ int rv515_ga_reset(struct radeon_device *rdev) bool reinit_cp; int i; - ENTER(); - reinit_cp = rdev->cp.ready; rdev->cp.ready = false; for (i = 0; i < rdev->usec_timeout; i++) { @@ -237,8 +230,6 @@ int rv515_gpu_reset(struct radeon_device *rdev) { uint32_t status; - ENTER(); - /* reset order likely matter */ status = RREG32(RBBM_STATUS); /* reset HDP */ @@ -286,13 +277,15 @@ static void rv515_vram_get_type(struct radeon_device *rdev) } } -void rv515_vram_info(struct radeon_device *rdev) +void rv515_mc_init(struct radeon_device *rdev) { fixed20_12 a; rv515_vram_get_type(rdev); - r100_vram_init_sizes(rdev); + radeon_vram_location(rdev, &rdev->mc, 0); + if (!(rdev->flags & RADEON_IS_AGP)) + radeon_gtt_location(rdev, &rdev->mc); /* FIXME: we should enforce default clock in case GPU is not in * default setup */ @@ -549,13 +542,15 @@ int rv515_init(struct radeon_device *rdev) radeon_get_clock_info(rdev->ddev); /* Initialize power management */ radeon_pm_init(rdev); - /* Get vram informations */ - rv515_vram_info(rdev); - /* Initialize memory controller (also test AGP) */ - r = r420_mc_init(rdev); - dbgprintf("mc vram location %x\n", rdev->mc.vram_location); - if (r) - return r; + /* initialize AGP */ + if (rdev->flags & RADEON_IS_AGP) { + r = radeon_agp_init(rdev); + if (r) { + radeon_agp_disable(rdev); + } + } + /* initialize memory controller */ + rv515_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ // r = radeon_fence_driver_init(rdev); diff --git a/drivers/video/drm/radeon/rv770.c b/drivers/video/drm/radeon/rv770.c index 78b21b4fe6..8aad4379c9 100644 --- a/drivers/video/drm/radeon/rv770.c +++ b/drivers/video/drm/radeon/rv770.c @@ -56,6 +56,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) r = radeon_gart_table_vram_pin(rdev); if (r) return r; + radeon_gart_restore(rdev); /* Setup L2 cache */ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | @@ -273,7 +274,8 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) /* * Core functions */ -static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, +static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, + u32 num_tile_pipes, u32 num_backends, u32 backend_disable_mask) { @@ -284,6 +286,7 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, u32 swizzle_pipe[R7XX_MAX_PIPES]; u32 cur_backend; u32 i; + bool force_no_swizzle; if (num_tile_pipes > R7XX_MAX_PIPES) num_tile_pipes = R7XX_MAX_PIPES; @@ -313,6 +316,18 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, if (enabled_backends_count != num_backends) num_backends = enabled_backends_count; + switch (rdev->family) { + case CHIP_RV770: + case CHIP_RV730: + force_no_swizzle = false; + break; + case CHIP_RV710: + case CHIP_RV740: + default: + force_no_swizzle = true; + break; + } + memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); switch (num_tile_pipes) { case 1: @@ -323,32 +338,71 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, swizzle_pipe[1] = 1; break; case 3: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 1; + } break; case 4: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 3; swizzle_pipe[3] = 1; + } break; case 5: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 4; swizzle_pipe[3] = 1; swizzle_pipe[4] = 3; + } break; case 6: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + swizzle_pipe[5] = 5; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 4; swizzle_pipe[3] = 5; swizzle_pipe[4] = 3; swizzle_pipe[5] = 1; + } break; case 7: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + swizzle_pipe[5] = 5; + swizzle_pipe[6] = 6; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 4; @@ -356,8 +410,19 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, swizzle_pipe[4] = 3; swizzle_pipe[5] = 1; swizzle_pipe[6] = 5; + } break; case 8: + if (force_no_swizzle) { + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + swizzle_pipe[5] = 5; + swizzle_pipe[6] = 6; + swizzle_pipe[7] = 7; + } else { swizzle_pipe[0] = 0; swizzle_pipe[1] = 2; swizzle_pipe[2] = 4; @@ -366,6 +431,7 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, swizzle_pipe[5] = 1; swizzle_pipe[6] = 7; swizzle_pipe[7] = 5; + } break; } @@ -385,8 +451,10 @@ static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, static void rv770_gpu_init(struct radeon_device *rdev) { int i, j, num_qd_pipes; + u32 ta_aux_cntl; u32 sx_debug_1; u32 smx_dc_ctl0; + u32 db_debug3; u32 num_gs_verts_per_thread; u32 vgt_gs_per_es; u32 gs_prim_buffer_depth = 0; @@ -515,6 +583,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) switch (rdev->config.rv770.max_tile_pipes) { case 1: + default: gb_tiling_config |= PIPE_TILING(0); break; case 2: @@ -526,16 +595,17 @@ static void rv770_gpu_init(struct radeon_device *rdev) case 8: gb_tiling_config |= PIPE_TILING(3); break; - default: - break; } + rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes; if (rdev->family == CHIP_RV770) gb_tiling_config |= BANK_TILING(1); else gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); + rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); gb_tiling_config |= GROUP_SIZE(0); + rdev->config.rv770.tiling_group_size = 256; if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { gb_tiling_config |= ROW_TILING(3); @@ -549,18 +619,27 @@ static void rv770_gpu_init(struct radeon_device *rdev) gb_tiling_config |= BANK_SWAPS(1); - backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, - rdev->config.rv770.max_backends, - (0xff << rdev->config.rv770.max_backends) & 0xff); - gb_tiling_config |= BACKEND_MAP(backend_map); + cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; + cc_rb_backend_disable |= + BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); - cc_gc_shader_pipe_config = + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; + cc_gc_shader_pipe_config |= INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK); cc_gc_shader_pipe_config |= INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK); - cc_rb_backend_disable = - BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); + if (rdev->family == CHIP_RV740) + backend_map = 0x28; + else + backend_map = r700_get_tile_pipe_to_backend_map(rdev, + rdev->config.rv770.max_tile_pipes, + (R7XX_MAX_BACKENDS - + r600_count_pipe_bits((cc_rb_backend_disable & + R7XX_MAX_BACKENDS_MASK) >> 16)), + (cc_rb_backend_disable >> 16)); + gb_tiling_config |= BACKEND_MAP(backend_map); + WREG32(GB_TILING_CONFIG, gb_tiling_config); WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); @@ -568,16 +647,13 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CGTS_SYS_TCC_DISABLE, 0); WREG32(CGTS_TCC_DISABLE, 0); - WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); - WREG32(CGTS_USER_TCC_DISABLE, 0); num_qd_pipes = - R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK); + R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK); WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK); @@ -587,10 +663,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); - WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | - SYNC_GRADIENT | - SYNC_WALKER | - SYNC_ALIGNER)); + ta_aux_cntl = RREG32(TA_CNTL_AUX); + WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO); sx_debug_1 = RREG32(SX_DEBUG_1); sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; @@ -601,14 +675,28 @@ static void rv770_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1); WREG32(SMX_DC_CTL0, smx_dc_ctl0); + if (rdev->family != CHIP_RV740) WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | GS_FLUSH_CTL(4) | ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); - if (rdev->family == CHIP_RV770) - WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); - else { + db_debug3 = RREG32(DB_DEBUG3); + db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); + switch (rdev->family) { + case CHIP_RV770: + case CHIP_RV740: + db_debug3 |= DB_CLK_OFF_DELAY(0x1f); + break; + case CHIP_RV710: + case CHIP_RV730: + default: + db_debug3 |= DB_CLK_OFF_DELAY(2); + break; + } + WREG32(DB_DEBUG3, db_debug3); + + if (rdev->family != CHIP_RV770) { db_debug4 = RREG32(DB_DEBUG4); db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER; WREG32(DB_DEBUG4, db_debug4); @@ -637,10 +725,10 @@ static void rv770_gpu_init(struct radeon_device *rdev) ALU_UPDATE_FIFO_HIWATER(0x8)); switch (rdev->family) { case CHIP_RV770: - sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1); - break; case CHIP_RV730: case CHIP_RV710: + sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1); + break; case CHIP_RV740: default: sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4); @@ -813,45 +901,13 @@ int rv770_mc_init(struct radeon_device *rdev) /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); - - if (rdev->mc.mc_vram_size > rdev->mc.aper_size) + rdev->mc.visible_vram_size = rdev->mc.aper_size; + /* FIXME remove this once we support unmappable VRAM */ + if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { rdev->mc.mc_vram_size = rdev->mc.aper_size; - - if (rdev->mc.real_vram_size > rdev->mc.aper_size) rdev->mc.real_vram_size = rdev->mc.aper_size; - - if (rdev->flags & RADEON_IS_AGP) { - /* gtt_size is setup by radeon_agp_init */ - rdev->mc.gtt_location = rdev->mc.agp_base; - tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; - /* Try to put vram before or after AGP because we - * we want SYSTEM_APERTURE to cover both VRAM and - * AGP so that GPU can catch out of VRAM/AGP access - */ - if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { - /* Enough place before */ - rdev->mc.vram_location = rdev->mc.gtt_location - - rdev->mc.mc_vram_size; - } else if (tmp > rdev->mc.mc_vram_size) { - /* Enough place after */ - rdev->mc.vram_location = rdev->mc.gtt_location + - rdev->mc.gtt_size; - } else { - /* Try to setup VRAM then AGP might not - * not work on some card - */ - rdev->mc.vram_location = 0x00000000UL; - rdev->mc.gtt_location = rdev->mc.mc_vram_size; } - } else { - rdev->mc.vram_location = 0x00000000UL; - rdev->mc.gtt_location = rdev->mc.mc_vram_size; - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; - } - rdev->mc.vram_start = rdev->mc.vram_location; - rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; - rdev->mc.gtt_start = rdev->mc.gtt_location; - rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; + r600_vram_gtt_location(rdev, &rdev->mc); /* FIXME: we should enforce default clock in case GPU is not in * default setup */ @@ -860,6 +916,7 @@ int rv770_mc_init(struct radeon_device *rdev) rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); return 0; } + int rv770_gpu_reset(struct radeon_device *rdev) { /* FIXME: implement any rv770 specific bits */ @@ -961,6 +1018,7 @@ int rv770_init(struct radeon_device *rdev) // r = radeon_fence_driver_init(rdev); // if (r) // return r; + /* initialize AGP */ if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); if (r) @@ -992,16 +1050,17 @@ int rv770_init(struct radeon_device *rdev) rdev->accel_working = false; } if (rdev->accel_working) { -// r = radeon_ib_pool_init(rdev); -// if (r) { -// DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); -// rdev->accel_working = false; -// } -// r = r600_ib_test(rdev); -// if (r) { -// DRM_ERROR("radeon: failled testing IB (%d).\n", r); -// rdev->accel_working = false; -// } +// r = radeon_ib_pool_init(rdev); +// if (r) { +// dev_err(rdev->dev, "IB initialization failed (%d).\n", r); +// rdev->accel_working = false; +// } else { +// r = r600_ib_test(rdev); +// if (r) { +// dev_err(rdev->dev, "IB test failed (%d).\n", r); +// rdev->accel_working = false; +// } +// } } return 0; } diff --git a/drivers/video/drm/radeon/rv770d.h b/drivers/video/drm/radeon/rv770d.h index b2789c7830..6a52939809 100644 --- a/drivers/video/drm/radeon/rv770d.h +++ b/drivers/video/drm/radeon/rv770d.h @@ -343,4 +343,6 @@ #define WAIT_UNTIL 0x8040 +#define SRBM_STATUS 0x0E50 + #endif