diff options
author | Dave Airlie <airlied@redhat.com> | 2010-02-25 13:44:04 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-26 16:23:23 +1000 |
commit | eb6b6d7cdd5548fa03a919d14615195600013be2 (patch) | |
tree | c499472ef28a903f94b09da9a24f66b021412813 /drivers/gpu/drm | |
parent | 30d6c72c4a760cfc9069ee100786e4d6cf6de59d (diff) | |
parent | 383be5d1789d9a7a2e77dca1cb0aca89507d069e (diff) |
Merge remote branch 'korg/drm-radeon-testing' into drm-next-stage
* korg/drm-radeon-testing: (62 commits)
drm/radeon/kms: update new pll algo
drm/radeon/kms: add support for square microtiles on r3xx-r5xx
drm/radeon/kms: force pinning buffer into visible VRAM
drm/radeon/kms/evergreen: fix typo in cursor code
drm/radeon/kms: implement reading active PCIE lanes on R600+
drm/radeon/kms: for downclocking non-mobility check PERFORMANCE state
drm/radeon/kms: simplify storing current and requested PM mode
drm/radeon: fixes for r6xx/r7xx gfx init
drm/radeon/rv740: fix backend setup
drm/radeon/kms: fix R3XX/R4XX memory controller initialization
[rfc] drm/radeon/kms: pm debugging check for vbl.
drm/radeon: Fix memory allocation failures in the preKMS command stream checking.
drm: Add generic multipart buffer.
drm/radeon/kms: simplify memory controller setup V2
drm/radeon: Add asic hook for dma copy to r200 cards.
drm/radeon/kms: Create asic structure for r300 pcie cards.
drm/radeon/kms: remove unused r600_gart_clear_page
drm/radeon/kms: remove HDP flushes from fence emit (v2)
drm/radeon/kms: add LVDS pll quirk for Dell Studio 15
drm/radeon/kms: simplify picking power state
...
Conflicts:
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/rv770.c
Diffstat (limited to 'drivers/gpu/drm')
61 files changed, 11854 insertions, 4730 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 39c5aa75b8f..abe3f446ca4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -4,7 +4,7 @@ ccflags-y := -Iinclude/drm -drm-y := drm_auth.o drm_bufs.o drm_cache.o \ +drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_context.o drm_dma.o drm_drawable.o \ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c new file mode 100644 index 00000000000..55d03ed0500 --- /dev/null +++ b/drivers/gpu/drm/drm_buffer.c @@ -0,0 +1,184 @@ +/************************************************************************** + * + * Copyright 2010 Pauli Nieminen. + * All Rights Reserved. + * + * 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, sub license, 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 (including the + * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. + * + * + **************************************************************************/ +/* + * Multipart buffer for coping data which is larger than the page size. + * + * Authors: + * Pauli Nieminen <suokkos-at-gmail-dot-com> + */ + +#include "drm_buffer.h" + +/** + * Allocate the drm buffer object. + * + * buf: Pointer to a pointer where the object is stored. + * size: The number of bytes to allocate. + */ +int drm_buffer_alloc(struct drm_buffer **buf, int size) +{ + int nr_pages = size / PAGE_SIZE + 1; + int idx; + + /* Allocating pointer table to end of structure makes drm_buffer + * variable sized */ + *buf = kzalloc(sizeof(struct drm_buffer) + nr_pages*sizeof(char *), + GFP_KERNEL); + + if (*buf == NULL) { + DRM_ERROR("Failed to allocate drm buffer object to hold" + " %d bytes in %d pages.\n", + size, nr_pages); + return -ENOMEM; + } + + (*buf)->size = size; + + for (idx = 0; idx < nr_pages; ++idx) { + + (*buf)->data[idx] = + kmalloc(min(PAGE_SIZE, size - idx * PAGE_SIZE), + GFP_KERNEL); + + + if ((*buf)->data[idx] == NULL) { + DRM_ERROR("Failed to allocate %dth page for drm" + " buffer with %d bytes and %d pages.\n", + idx + 1, size, nr_pages); + goto error_out; + } + + } + + return 0; + +error_out: + + /* Only last element can be null pointer so check for it first. */ + if ((*buf)->data[idx]) + kfree((*buf)->data[idx]); + + for (--idx; idx >= 0; --idx) + kfree((*buf)->data[idx]); + + kfree(*buf); + return -ENOMEM; +} +EXPORT_SYMBOL(drm_buffer_alloc); + +/** + * Copy the user data to the begin of the buffer and reset the processing + * iterator. + * + * user_data: A pointer the data that is copied to the buffer. + * size: The Number of bytes to copy. + */ +extern int drm_buffer_copy_from_user(struct drm_buffer *buf, + void __user *user_data, int size) +{ + int nr_pages = size / PAGE_SIZE + 1; + int idx; + + if (size > buf->size) { + DRM_ERROR("Requesting to copy %d bytes to a drm buffer with" + " %d bytes space\n", + size, buf->size); + return -EFAULT; + } + + for (idx = 0; idx < nr_pages; ++idx) { + + if (DRM_COPY_FROM_USER(buf->data[idx], + user_data + idx * PAGE_SIZE, + min(PAGE_SIZE, size - idx * PAGE_SIZE))) { + DRM_ERROR("Failed to copy user data (%p) to drm buffer" + " (%p) %dth page.\n", + user_data, buf, idx); + return -EFAULT; + + } + } + buf->iterator = 0; + return 0; +} +EXPORT_SYMBOL(drm_buffer_copy_from_user); + +/** + * Free the drm buffer object + */ +void drm_buffer_free(struct drm_buffer *buf) +{ + + if (buf != NULL) { + + int nr_pages = buf->size / PAGE_SIZE + 1; + int idx; + for (idx = 0; idx < nr_pages; ++idx) + kfree(buf->data[idx]); + + kfree(buf); + } +} +EXPORT_SYMBOL(drm_buffer_free); + +/** + * Read an object from buffer that may be split to multiple parts. If object + * is not split function just returns the pointer to object in buffer. But in + * case of split object data is copied to given stack object that is suplied + * by caller. + * + * The processing location of the buffer is also advanced to the next byte + * after the object. + * + * objsize: The size of the objet in bytes. + * stack_obj: A pointer to a memory location where object can be copied. + */ +void *drm_buffer_read_object(struct drm_buffer *buf, + int objsize, void *stack_obj) +{ + int idx = drm_buffer_index(buf); + int page = drm_buffer_page(buf); + void *obj = 0; + + if (idx + objsize <= PAGE_SIZE) { + obj = &buf->data[page][idx]; + } else { + /* The object is split which forces copy to temporary object.*/ + int beginsz = PAGE_SIZE - idx; + memcpy(stack_obj, &buf->data[page][idx], beginsz); + + memcpy(stack_obj + beginsz, &buf->data[page + 1][0], + objsize - beginsz); + + obj = stack_obj; + } + + drm_buffer_advance(buf, objsize); + return obj; +} +EXPORT_SYMBOL(drm_buffer_read_object); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ab6c9733041..f97e7c42ac8 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/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/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 1cc7b937b1e..b46f115d1c2 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -30,6 +30,9 @@ $(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable $(call if_changed,mkregtable) +$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable + $(call if_changed,mkregtable) + $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h $(obj)/r200.o: $(obj)/r200_reg_safe.h @@ -42,6 +45,8 @@ $(obj)/r420.o: $(obj)/r420_reg_safe.h $(obj)/rs600.o: $(obj)/rs600_reg_safe.h +$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h + radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ radeon_irq.o r300_cmdbuf.o r600_cp.o # add KMS driver @@ -54,7 +59,8 @@ radeon-y += radeon_device.o radeon_kms.o \ radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ - r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o + r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ + evergreen.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 91ad0d1c1b1..6732b5dd8ff 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 Advanced Micro Devices, Inc. + * Copyright 2006-2007 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"), @@ -20,10 +20,12 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/****************************************************************************/ + +/****************************************************************************/ /*Portion I: Definitions shared between VBIOS and Driver */ /****************************************************************************/ + #ifndef _ATOMBIOS_H #define _ATOMBIOS_H @@ -40,39 +42,46 @@ #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 + +#define ATOM_DAC_A 0 #define ATOM_DAC_B 1 #define ATOM_EXT_DAC 2 #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 -#define ATOM_SCALER_DISABLE 0 -#define ATOM_SCALER_CENTER 1 -#define ATOM_SCALER_EXPANSION 2 -#define ATOM_SCALER_MULTI_EX 3 +#define ATOM_SCALER_DISABLE 0 +#define ATOM_SCALER_CENTER 1 +#define ATOM_SCALER_EXPANSION 2 +#define ATOM_SCALER_MULTI_EX 3 #define ATOM_DISABLE 0 #define ATOM_ENABLE 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 @@ -114,7 +124,7 @@ typedef unsigned short USHORT; #define ATOM_DAC2_CV ATOM_DAC1_CV #define ATOM_DAC2_NTSC ATOM_DAC1_NTSC #define ATOM_DAC2_PAL ATOM_DAC1_PAL - + #define ATOM_PM_ON 0 #define ATOM_PM_STANDBY 1 #define ATOM_PM_SUSPEND 2 @@ -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,19 +156,19 @@ 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_MAX_SIZE_OF_FAKE_DESKTOP_STRING ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING +#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 -#pragma pack(1) /* BIOS data must use byte aligment */ +#pragma pack(1) /* BIOS data must use byte aligment */ /* Define offset to location of ROM header. */ @@ -165,367 +176,410 @@ typedef unsigned short USHORT; #define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L #define OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE 0x94 -#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE 20 /* including the terminator 0x0! */ +#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE 20 /* including the terminator 0x0! */ #define OFFSET_TO_GET_ATOMBIOS_STRINGS_NUMBER 0x002f #define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x006e /* Common header for all ROM Data tables. - Every table pointed _ATOM_MASTER_DATA_TABLE has this common header. + 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 { - 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; - -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 */ - USHORT usBiosRuntimeSegmentAddress; - USHORT usProtectedModeInfoOffset; - USHORT usConfigFilenameOffset; - USHORT usCRC_BlockOffset; - USHORT usBIOS_BootupMessageOffset; - USHORT usInt10Offset; - USHORT usPciBusDevInitCode; - USHORT usIoBaseAddress; - USHORT usSubsystemVendorID; - USHORT usSubsystemID; - USHORT usPCI_InfoOffset; - USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */ - USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */ - UCHAR ucExtendedFunctionCode; - UCHAR ucReserved; -} ATOM_ROM_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; + +typedef struct _ATOM_ROM_HEADER +{ + ATOM_COMMON_TABLE_HEADER sHeader; + UCHAR |