Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 358094
b: refs/heads/master
c: 62cd2fa
h: refs/heads/master
v: v3
  • Loading branch information
Dave Airlie committed Feb 8, 2013
1 parent 6ea3ed0 commit a6deab0
Show file tree
Hide file tree
Showing 90 changed files with 4,806 additions and 3,402 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ae1287865f5361fa138d4d3b1b6277908b54eac9
refs/heads/master: 62cd2fa82a38cb3d653517822c62a39cdbb5f365
63 changes: 49 additions & 14 deletions trunk/Documentation/DocBook/drm.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -978,10 +978,25 @@ int max_width, max_height;</synopsis>
If the parameters are deemed valid, drivers then create, initialize and
return an instance of struct <structname>drm_framebuffer</structname>.
If desired the instance can be embedded in a larger driver-specific
structure. The new instance is initialized with a call to
<function>drm_framebuffer_init</function> which takes a pointer to DRM
frame buffer operations (struct
<structname>drm_framebuffer_funcs</structname>). Frame buffer operations are
structure. Drivers must fill its <structfield>width</structfield>,
<structfield>height</structfield>, <structfield>pitches</structfield>,
<structfield>offsets</structfield>, <structfield>depth</structfield>,
<structfield>bits_per_pixel</structfield> and
<structfield>pixel_format</structfield> fields from the values passed
through the <parameter>drm_mode_fb_cmd2</parameter> argument. They
should call the <function>drm_helper_mode_fill_fb_struct</function>
helper function to do so.
</para>

<para>
The initailization of the new framebuffer instance is finalized with a
call to <function>drm_framebuffer_init</function> which takes a pointer
to DRM frame buffer operations (struct
<structname>drm_framebuffer_funcs</structname>). Note that this function
publishes the framebuffer and so from this point on it can be accessed
concurrently from other threads. Hence it must be the last step in the
driver's framebuffer initialization sequence. Frame buffer operations
are
<itemizedlist>
<listitem>
<synopsis>int (*create_handle)(struct drm_framebuffer *fb,
Expand Down Expand Up @@ -1022,16 +1037,16 @@ int max_width, max_height;</synopsis>
</itemizedlist>
</para>
<para>
After initializing the <structname>drm_framebuffer</structname>
instance drivers must fill its <structfield>width</structfield>,
<structfield>height</structfield>, <structfield>pitches</structfield>,
<structfield>offsets</structfield>, <structfield>depth</structfield>,
<structfield>bits_per_pixel</structfield> and
<structfield>pixel_format</structfield> fields from the values passed
through the <parameter>drm_mode_fb_cmd2</parameter> argument. They
should call the <function>drm_helper_mode_fill_fb_struct</function>
helper function to do so.
</para>
The lifetime of a drm framebuffer is controlled with a reference count,
drivers can grab additional references with
<function>drm_framebuffer_reference</function> </para> and drop them
again with <function>drm_framebuffer_unreference</function>. For
driver-private framebuffers for which the last reference is never
dropped (e.g. for the fbdev framebuffer when the struct
<structname>drm_framebuffer</structname> is embedded into the fbdev
helper struct) drivers can manually clean up a framebuffer at module
unload time with
<function>drm_framebuffer_unregister_private</function>.
</sect2>
<sect2>
<title>Output Polling</title>
Expand All @@ -1043,6 +1058,22 @@ int max_width, max_height;</synopsis>
operation.
</para>
</sect2>
<sect2>
<title>Locking</title>
<para>
Beside some lookup structures with their own locking (which is hidden
behind the interface functions) most of the modeset state is protected
by the <code>dev-&lt;mode_config.lock</code> mutex and additionally
per-crtc locks to allow cursor updates, pageflips and similar operations
to occur concurrently with background tasks like output detection.
Operations which cross domains like a full modeset always grab all
locks. Drivers there need to protect resources shared between crtcs with
additional locking. They also need to be careful to always grab the
relevant crtc locks if a modset functions touches crtc state, e.g. for
load detection (which does only grab the <code>mode_config.lock</code>
to allow concurrent screen updates on live crtcs).
</para>
</sect2>
</sect1>

<!-- Internals: kms initialization and cleanup -->
Expand Down Expand Up @@ -1609,6 +1640,10 @@ void intel_crt_init(struct drm_device *dev)
make its properties available to applications.
</para>
</sect2>
<sect2>
<title>KMS API Functions</title>
!Edrivers/gpu/drm/drm_crtc.c
</sect2>
</sect1>

<!-- Internals: kms helper functions -->
Expand Down
27 changes: 23 additions & 4 deletions trunk/Documentation/EDID/HOWTO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,30 @@ Makefile environment are given here.
To create binary EDID and C source code files from the existing data
material, simply type "make".

If you want to create your own EDID file, copy the file 1024x768.S and
replace the settings with your own data. The CRC value in the last line
If you want to create your own EDID file, copy the file 1024x768.S,
replace the settings with your own data and add a new target to the
Makefile. Please note that the EDID data structure expects the timing
values in a different way as compared to the standard X11 format.

X11:
HTimings: hdisp hsyncstart hsyncend htotal
VTimings: vdisp vsyncstart vsyncend vtotal

EDID:
#define XPIX hdisp
#define XBLANK htotal-hdisp
#define XOFFSET hsyncstart-hdisp
#define XPULSE hsyncend-hsyncstart

#define YPIX vdisp
#define YBLANK vtotal-vdisp
#define YOFFSET (63+(vsyncstart-vdisp))
#define YPULSE (63+(vsyncend-vsyncstart))

The CRC value in the last line
#define CRC 0x55
is a bit tricky. After a first version of the binary data set is
created, it must be be checked with the "edid-decode" utility which will
also is a bit tricky. After a first version of the binary data set is
created, it must be checked with the "edid-decode" utility which will
most probably complain about a wrong CRC. Fortunately, the utility also
displays the correct CRC which must then be inserted into the source
file. After the make procedure is repeated, the EDID data set is ready
Expand Down
88 changes: 35 additions & 53 deletions trunk/drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ struct intel_gtt_driver {
};

static struct _intel_private {
struct intel_gtt base;
const struct intel_gtt_driver *driver;
struct pci_dev *pcidev; /* device one */
struct pci_dev *bridge_dev;
Expand All @@ -75,7 +74,18 @@ static struct _intel_private {
struct resource ifp_resource;
int resource_valid;
struct page *scratch_page;
phys_addr_t scratch_page_dma;
int refcount;
/* Whether i915 needs to use the dmar apis or not. */
unsigned int needs_dmar : 1;
phys_addr_t gma_bus_addr;
/* Size of memory reserved for graphics by the BIOS */
unsigned int stolen_size;
/* Total number of gtt entries. */
unsigned int gtt_total_entries;
/* Part of the gtt that is mappable by the cpu, for those chips where
* this is not the full gtt. */
unsigned int gtt_mappable_entries;
} intel_private;

#define INTEL_GTT_GEN intel_private.driver->gen
Expand Down Expand Up @@ -291,15 +301,15 @@ static int intel_gtt_setup_scratch_page(void)
get_page(page);
set_pages_uc(page, 1);

if (intel_private.base.needs_dmar) {
if (intel_private.needs_dmar) {
dma_addr = pci_map_page(intel_private.pcidev, page, 0,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(intel_private.pcidev, dma_addr))
return -EINVAL;

intel_private.base.scratch_page_dma = dma_addr;
intel_private.scratch_page_dma = dma_addr;
} else
intel_private.base.scratch_page_dma = page_to_phys(page);
intel_private.scratch_page_dma = page_to_phys(page);

intel_private.scratch_page = page;

Expand Down Expand Up @@ -506,7 +516,7 @@ static unsigned int intel_gtt_total_entries(void)
/* On previous hardware, the GTT size was just what was
* required to map the aperture.
*/
return intel_private.base.gtt_mappable_entries;
return intel_private.gtt_mappable_entries;
}
}

Expand Down Expand Up @@ -546,7 +556,7 @@ static unsigned int intel_gtt_mappable_entries(void)
static void intel_gtt_teardown_scratch_page(void)
{
set_pages_wb(intel_private.scratch_page, 1);
pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma,
pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
put_page(intel_private.scratch_page);
__free_page(intel_private.scratch_page);
Expand All @@ -572,8 +582,8 @@ static int intel_gtt_init(void)
if (ret != 0)
return ret;

intel_private.base.gtt_mappable_entries = intel_gtt_mappable_entries();
intel_private.base.gtt_total_entries = intel_gtt_total_entries();
intel_private.gtt_mappable_entries = intel_gtt_mappable_entries();
intel_private.gtt_total_entries = intel_gtt_total_entries();

/* save the PGETBL reg for resume */
intel_private.PGETBL_save =
Expand All @@ -585,10 +595,10 @@ static int intel_gtt_init(void)

dev_info(&intel_private.bridge_dev->dev,
"detected gtt size: %dK total, %dK mappable\n",
intel_private.base.gtt_total_entries * 4,
intel_private.base.gtt_mappable_entries * 4);
intel_private.gtt_total_entries * 4,
intel_private.gtt_mappable_entries * 4);

gtt_map_size = intel_private.base.gtt_total_entries * 4;
gtt_map_size = intel_private.gtt_total_entries * 4;

intel_private.gtt = NULL;
if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2)
Expand All @@ -602,13 +612,12 @@ static int intel_gtt_init(void)
iounmap(intel_private.registers);
return -ENOMEM;
}
intel_private.base.gtt = intel_private.gtt;

global_cache_flush(); /* FIXME: ? */

intel_private.base.stolen_size = intel_gtt_stolen_size();
intel_private.stolen_size = intel_gtt_stolen_size();

intel_private.base.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2;
intel_private.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2;

ret = intel_gtt_setup_scratch_page();
if (ret != 0) {
Expand All @@ -623,7 +632,7 @@ static int intel_gtt_init(void)
pci_read_config_dword(intel_private.pcidev, I915_GMADDR,
&gma_addr);

intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK);
intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK);

return 0;
}
Expand All @@ -634,8 +643,7 @@ static int intel_fake_agp_fetch_size(void)
unsigned int aper_size;
int i;

aper_size = (intel_private.base.gtt_mappable_entries << PAGE_SHIFT)
/ MB(1);
aper_size = (intel_private.gtt_mappable_entries << PAGE_SHIFT) / MB(1);

for (i = 0; i < num_sizes; i++) {
if (aper_size == intel_fake_agp_sizes[i].size) {
Expand Down Expand Up @@ -779,7 +787,7 @@ static int intel_fake_agp_configure(void)
return -EIO;

intel_private.clear_fake_agp = true;
agp_bridge->gart_bus_addr = intel_private.base.gma_bus_addr;
agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;

return 0;
}
Expand Down Expand Up @@ -841,12 +849,9 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
{
int ret = -EINVAL;

if (intel_private.base.do_idle_maps)
return -ENODEV;

if (intel_private.clear_fake_agp) {
int start = intel_private.base.stolen_size / PAGE_SIZE;
int end = intel_private.base.gtt_mappable_entries;
int start = intel_private.stolen_size / PAGE_SIZE;
int end = intel_private.gtt_mappable_entries;
intel_gtt_clear_range(start, end - start);
intel_private.clear_fake_agp = false;
}
Expand All @@ -857,7 +862,7 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
if (mem->page_count == 0)
goto out;

if (pg_start + mem->page_count > intel_private.base.gtt_total_entries)
if (pg_start + mem->page_count > intel_private.gtt_total_entries)
goto out_err;

if (type != mem->type)
Expand All @@ -869,7 +874,7 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
if (!mem->is_flushed)
global_cache_flush();

if (intel_private.base.needs_dmar) {
if (intel_private.needs_dmar) {
struct sg_table st;

ret = intel_gtt_map_memory(mem->pages, mem->page_count, &st);
Expand All @@ -895,7 +900,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
unsigned int i;

for (i = first_entry; i < (first_entry + num_entries); i++) {
intel_private.driver->write_entry(intel_private.base.scratch_page_dma,
intel_private.driver->write_entry(intel_private.scratch_page_dma,
i, 0);
}
readl(intel_private.gtt+i-1);
Expand All @@ -908,12 +913,9 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
if (mem->page_count == 0)
return 0;

if (intel_private.base.do_idle_maps)
return -ENODEV;

intel_gtt_clear_range(pg_start, mem->page_count);

if (intel_private.base.needs_dmar) {
if (intel_private.needs_dmar) {
intel_gtt_unmap_memory(mem->sg_list, mem->num_sg);
mem->sg_list = NULL;
mem->num_sg = 0;
Expand Down Expand Up @@ -1070,24 +1072,6 @@ static void i965_write_entry(dma_addr_t addr,
writel(addr | pte_flags, intel_private.gtt + entry);
}

/* Certain Gen5 chipsets require require idling the GPU before
* unmapping anything from the GTT when VT-d is enabled.
*/
static inline int needs_idle_maps(void)
{
#ifdef CONFIG_INTEL_IOMMU
const unsigned short gpu_devid = intel_private.pcidev->device;

/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
*/
if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
intel_iommu_gfx_mapped)
return 1;
#endif
return 0;
}

static int i9xx_setup(void)
{
Expand Down Expand Up @@ -1116,9 +1100,6 @@ static int i9xx_setup(void)
break;
}

if (needs_idle_maps())
intel_private.base.do_idle_maps = 1;

intel_i9xx_setup_flush();

return 0;
Expand Down Expand Up @@ -1390,9 +1371,10 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
}
EXPORT_SYMBOL(intel_gmch_probe);

struct intel_gtt *intel_gtt_get(void)
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size)
{
return &intel_private.base;
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
*stolen_size = intel_private.stolen_size;
}
EXPORT_SYMBOL(intel_gtt_get);

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/gpu/drm/ast/ast_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ static int ast_drm_thaw(struct drm_device *dev)
ast_post_gpu(dev);

drm_mode_config_reset(dev);
mutex_lock(&dev->mode_config.mutex);
drm_modeset_lock_all(dev);
drm_helper_resume_force_mode(dev);
mutex_unlock(&dev->mode_config.mutex);
drm_modeset_unlock_all(dev);

console_lock();
ast_fbdev_set_suspend(dev, 0);
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/ast/ast_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ struct ast_private {

struct drm_gem_object *cursor_cache;
uint64_t cursor_cache_gpu_addr;
/* Acces to this cache is protected by the crtc->mutex of the only crtc
* we have. */
struct ttm_bo_kmap_obj cache_kmap;
int next_cursor;
};
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/ast/ast_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ static void ast_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_fini(&afbdev->helper);

vfree(afbdev->sysram);
drm_framebuffer_unregister_private(&afb->base);
drm_framebuffer_cleanup(&afb->base);
}

Expand Down
Loading

0 comments on commit a6deab0

Please sign in to comment.