On Wed, 2008-11-05 at 16:49 -0800, Jesse Barnes wrote:
> Adds support for DRM based mode setting on Intel integrated graphics chips.

Might be nice to note what hardware is/isn't supported and tested here.
For example, native HDMI is missing from the 2d driver it looks like,
and we still need to write DP support.

My major concern is basically license clarification.

> diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h
> new file mode 100644
> index 0000000..b122ea1
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/dvo.h
> @@ -0,0 +1,159 @@
> +/*
> + * Copyright © 2006 Eric Anholt
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and 
> its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that 
> copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission.  The copyright holders make no representations
> + * about the suitability of this software for any purpose.  It is provided 
> "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 
> SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 
> USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
> PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +#ifndef _INTEL_DVO_H 
> +#define _INTEL_DVO_H 
> +
> +#include <linux/i2c.h>
> +#include "drmP.h"
> +#include "drm.h"
> +#include "drm_crtc.h"
> +#include "intel_drv.h"
> +
> +struct intel_dvo_device {
> +     char *name;
> +     int type;
> +     /* DVOA/B/C output register */
> +     u32 dvo_reg;
> +     /* GPIO register used for i2c bus to control this device */
> +     u32 gpio;
> +     int slave_addr;
> +     struct intel_i2c_chan *i2c_bus;
> +
> +     const struct intel_dvo_dev_ops *dev_ops;
> +     void *dev_priv;
> +
> +     struct drm_display_mode *panel_fixed_mode;
> +     bool panel_wants_dither;
> +};
> +
> +struct intel_dvo_dev_ops {
> +     /*
> +      * Initialize the device at startup time.
> +      * Returns NULL if the device does not exist.
> +      */
> +     bool (*init)(struct intel_dvo_device *dvo,
> +                  struct intel_i2c_chan *i2cbus);
> +
> +     /*
> +      * Called to allow the output a chance to create properties after the
> +      * RandR objects have been created.
> +      */
> +     void (*create_resources)(struct intel_dvo_device *dvo);
> +
> +     /*
> +      * Turn on/off output or set intermediate power levels if available.
> +      *
> +      * Unsupported intermediate modes drop to the lower power setting.
> +      * If the  mode is DPMSModeOff, the output must be disabled,
> +      * as the DPLL may be disabled afterwards.
> +      */
> +     void (*dpms)(struct intel_dvo_device *dvo, int mode);
> +
> +     /*
> +      * Saves the output's state for restoration on VT switch.
> +      */
> +     void (*save)(struct intel_dvo_device *dvo);
> +
> +     /*
> +      * Restore's the output's state at VT switch.
> +      */
> +     void (*restore)(struct intel_dvo_device *dvo);
> +
> +     /*
> +      * Callback for testing a video mode for a given output.
> +      *
> +      * This function should only check for cases where a mode can't
> +      * be supported on the output specifically, and not represent
> +      * generic CRTC limitations.
> +      *
> +      * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
> +      */
> +     int (*mode_valid)(struct intel_dvo_device *dvo,
> +                       struct drm_display_mode *mode);
> +
> +     /*
> +      * Callback to adjust the mode to be set in the CRTC.
> +      *
> +      * This allows an output to adjust the clock or even the entire set of
> +      * timings, which is used for panels with fixed timings or for
> +      * buses with clock limitations.
> +      */
> +     bool (*mode_fixup)(struct intel_dvo_device *dvo,
> +                        struct drm_display_mode *mode,
> +                        struct drm_display_mode *adjusted_mode);
> +
> +     /*
> +      * Callback for preparing mode changes on an output
> +      */
> +     void (*prepare)(struct intel_dvo_device *dvo);
> +
> +     /*
> +      * Callback for committing mode changes on an output
> +      */
> +     void (*commit)(struct intel_dvo_device *dvo);
> +
> +     /*
> +      * Callback for setting up a video mode after fixups have been made.
> +      *
> +      * This is only called while the output is disabled.  The dpms callback
> +      * must be all that's necessary for the output, to turn the output on
> +      * after this function is called.
> +      */
> +     void (*mode_set)(struct intel_dvo_device *dvo,
> +                      struct drm_display_mode *mode,
> +                      struct drm_display_mode *adjusted_mode);
> +
> +     /*
> +      * Probe for a connected output, and return detect_status.
> +      */
> +     enum drm_connector_status (*detect)(struct intel_dvo_device *dvo);
> +
> +     /**
> +      * Query the device for the modes it provides.
> +      *
> +      * This function may also update MonInfo, mm_width, and mm_height.
> +      *
> +      * \return singly-linked list of modes or NULL if no modes found.
> +      */
> +     struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo);
> +
> +#ifdef RANDR_12_INTERFACE
> +     /**
> +      * Callback when an output's property has changed.
> +      */
> +     bool (*set_property)(struct intel_dvo_device *dvo,
> +                          struct drm_property *property, uint64_t val);
> +#endif

RANDR_12_INTERFACE?

> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 1c87509..6986cc3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
 
> +#if defined(CONFIG_DRM_I915_KMS)
> +MODULE_DEVICE_TABLE(pci, pciidlist);
> +#endif
> +

I'm assuming the #ifdef here is because we can't actually attach to the
pci device unless we're doing modesetting and won't be fighting fbdev
for it (that is, if we win we keep them out).  But I don't think this
achieves that on its own, and I don't see it referenced, so I'm just
confused what it does.

> @@ -146,6 +159,23 @@ static struct drm_driver driver = {
>  static int __init i915_init(void)
>  {
>       driver.num_ioctls = i915_max_ioctl;
> +
> +     /* if enabled by default */
> +#if defined(CONFIG_DRM_I915_KMS) && defined(CONFIG_X86)
> +     driver.driver_features |= DRIVER_MODESET;
> +     if (i915_modeset == 0)
> +             driver.driver_features &= ~DRIVER_MODESET;
> +#endif
> +     if (i915_modeset == 1)
> +             driver.driver_features |= DRIVER_MODESET;

So I'm trying to get this straight: We default to KMS disabled, unless
you're on 32-bit and have selected the KMS option?  What's the logic
here?

> +
> +     /* if the vga console setting is enabled still
> +      * let modprobe override it */
> +#ifdef CONFIG_VGA_CONSOLE
> +     if (vgacon_text_force() && i915_modeset == -1)
> +             driver.driver_features &= ~DRIVER_MODESET;
> +#endif
> +
>       return drm_init(&driver);
>  }

> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index d5c909a..e11c6f3 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2523,11 +2526,21 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
>       }
>       obj_priv = obj->driver_private;
>  
> -     ret = i915_gem_object_pin(obj, args->alignment);
> -     if (ret != 0) {
> -             drm_gem_object_unreference(obj);
> -             mutex_unlock(&dev->struct_mutex);
> -             return ret;
> +     if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
> +             DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
> +                       args->handle);
> +             return -EINVAL;

lock leak

> @@ -2813,7 +2839,8 @@ i915_gem_init_hws(struct drm_device *dev)
>       int ret;
>  
>       /* If we need a physical address for the status page, it's already
> -      * initialized at driver load time.
> +      * initialized at driver load time, unless kernel modesetting is
> +      * active.
>        */

wtf?

> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index ccd3e7d..2ea58ce 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c

Could we dump this diff if we're just #if 0ing it for now?  It shouldn't
be hard to hook it back up, but it seems like throwing it out for the
moment would be better.

Also, are things getting set so that kms sets the
aware-of-pre/postmodeset bit so that we turn vblank off when not used?

> @@ -30,6 +30,7 @@
>  #include "drm.h"
>  #include "i915_drm.h"
>  #include "i915_drv.h"
> +#include "intel_drv.h"
>  
>  #define MAX_NOPID ((u32)~0)
>  
> @@ -39,6 +40,15 @@
>                                   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
>                                   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
>  
> +#define I915_PIPE_VBLANK_STATUS      (PIPE_START_VBLANK_INTERRUPT_STATUS |\
> +                              PIPE_VBLANK_INTERRUPT_STATUS)
> +
> +#define I915_PIPE_VBLANK_ENABLE      (PIPE_START_VBLANK_INTERRUPT_ENABLE |\
> +                              PIPE_VBLANK_INTERRUPT_ENABLE)
> +
> +#define DRM_I915_VBLANK_PIPE_ALL     (DRM_I915_VBLANK_PIPE_A | \
> +                                      DRM_I915_VBLANK_PIPE_B)
> +
>  void
>  i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
>  {
> @@ -424,6 +434,86 @@ void i915_disable_vblank(struct drm_device *dev, int 
> pipe)
>       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
>  }
>  
> +void i915_enable_interrupt (struct drm_device *dev)
> +{
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +#if 0
> +     struct drm_connector *o;
> +
> +     if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
> +             if (dev->mode_config.num_connector)
> +                     dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT;
> +     } else {
> +             if (dev->mode_config.num_connector)
> +                     dev_priv->irq_mask_reg &= 
> ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
> +
> +             /*
> +              * Enable global interrupts for hotplug - not
> +              * a pipeA event
> +              */
> +             I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) |
> +                        PIPE_HOTPLUG_INTERRUPT_ENABLE |
> +                        PIPE_HOTPLUG_TV_INTERRUPT_ENABLE |
> +                        PIPE_HOTPLUG_TV_INTERRUPT_STATUS |
> +                        PIPE_HOTPLUG_INTERRUPT_STATUS);
> +     }
> +
> +     if (!(dev_priv->irq_mask_reg & I915_DISPLAY_PORT_INTERRUPT) ||
> +         !(dev_priv->irq_mask_reg & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)) {
> +             u32 temp = 0;
> +
> +             if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
> +                     temp = I915_READ(PORT_HOTPLUG_EN);
> +
> +                     /* Activate the CRT */
> +                     temp |= CRT_HOTPLUG_INT_EN;
> +             }
> +
> +             if (IS_I9XX(dev)) {
> +                     /* SDVOB */
> +                     o = intel_sdvo_find(dev, 1);
> +                     if (o && intel_sdvo_supports_hotplug(o)) {
> +                             intel_sdvo_set_hotplug(o, 1);
> +                             temp |= SDVOB_HOTPLUG_INT_EN;
> +                     }
> +
> +                     /* SDVOC */
> +                     o = intel_sdvo_find(dev, 0);
> +                     if (o && intel_sdvo_supports_hotplug(o)) {
> +                             intel_sdvo_set_hotplug(o, 1);
> +                             temp |= SDVOC_HOTPLUG_INT_EN;
> +                     }
> +
> +                     I915_WRITE(SDVOB, I915_READ(SDVOB) |
> +                                SDVO_INTERRUPT_ENABLE);
> +                     I915_WRITE(SDVOC, I915_READ(SDVOC) |
> +                                SDVO_INTERRUPT_ENABLE);
> +
> +                     /* TV */
> +                     I915_WRITE(TV_DAC, I915_READ(TV_DAC) |
> +                                TVDAC_STATE_CHG_EN);
> +             } else {
> +                     /* FIXME: DVO */
> +             }
> +
> +             if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
> +                     I915_WRITE(PORT_HOTPLUG_EN, temp);
> +
> +                     DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
> +                     DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
> +
> +                     I915_WRITE(PORT_HOTPLUG_STAT,
> +                                I915_READ(PORT_HOTPLUG_STAT));
> +             }
> +     }
> +
> +     i915_vblank_configure(dev, dev_priv->vblank_pipe);
> +#endif
> +     opregion_enable_asle(dev);
> +     dev_priv->irq_enabled = 1;
> +}
> +
> +
>  /* Set the vblank monitor pipe
>   */
>  int i915_vblank_pipe_set(struct drm_device *dev, void *data,
> @@ -484,6 +574,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
>  {
>       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>  
> +     atomic_set(&dev_priv->irq_received, 0);
> +
>       I915_WRITE(HWSTAM, 0xeffe);
>       I915_WRITE(IMR, 0xffffffff);
>       I915_WRITE(IER, 0x0);
> diff --git a/drivers/gpu/drm/i915/i915_suspend.c 
> b/drivers/gpu/drm/i915/i915_suspend.c
> index 5ddc6e5..1662213 100644
> --- a/drivers/gpu/drm/i915/i915_suspend.c
> +++ b/drivers/gpu/drm/i915/i915_suspend.c
> @@ -1,5 +1,7 @@
>  /*
>   *
> + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
> + * All Rights Reserved.
>   * Copyright 2008 (c) Intel Corporation
>   *   Jesse Barnes <[EMAIL PROTECTED]>
>   *

This is kind of surprising in the middle of this commit.  Perhaps it
should be separated out to note what happened.

> diff --git a/drivers/gpu/drm/i915/intel_crt.c 
> b/drivers/gpu/drm/i915/intel_crt.c
> new file mode 100644
> index 0000000..2505d98
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_crt.c

> +static void intel_crt_save(struct drm_connector *connector)
> +{
> +     
> +}
> +
> +static void intel_crt_restore(struct drm_connector *connector)
> +{
> +
> +}

Are the save/restore paths actually used?  It looks like no.  If so,
they should probably not get included in the initial commit.  On the
other hand, it seems like for DVO in particular having the save/restore
next to the other code is a really good plan.

> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> new file mode 100644
> index 0000000..09f6350
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_display.c

> +void
> +intel_set_vblank(struct drm_device *dev)
> +{
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     struct drm_crtc *crtc;
> +     struct intel_crtc *intel_crtc;
> +     int vbl_pipe = 0;
> +
> +     list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> +             intel_crtc = to_intel_crtc(crtc);
> +
> +             if (crtc->enabled)
> +                     vbl_pipe |= (1<<intel_crtc->pipe);
> +     }
> +
> +     dev_priv->vblank_pipe = vbl_pipe;
> +//   i915_enable_interrupt(dev);
> +}

// comments

> +static int intel_crtc_cursor_set(struct drm_crtc *crtc,
> +                              struct drm_file *file_priv,
> +                              uint32_t handle,
> +                              uint32_t width, uint32_t height)
> +{
> +     struct drm_device *dev = crtc->dev;
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +     struct drm_gem_object *bo;
> +     struct drm_i915_gem_object *obj_priv;
> +     int pipe = intel_crtc->pipe;
> +     uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
> +     uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
> +     uint32_t temp;
> +     size_t addr;
> +
> +     DRM_DEBUG("\n");
> +
> +     /* if we want to turn of the cursor ignore width and height */

s/of/off/

> +     if (!handle) {
> +             DRM_DEBUG("cursor off\n");
> +             /* turn of the cursor */
> +             temp = 0;
> +             temp |= CURSOR_MODE_DISABLE;
> +
> +             I915_WRITE(control, temp);
> +             I915_WRITE(base, 0);
> +             return 0;
> +     }
> +
> +     /* Currently we only support 64x64 cursors */
> +     if (width != 64 || height != 64) {
> +             DRM_ERROR("we currently only support 64x64 cursors\n");
> +             return -EINVAL;
> +     }
> +
> +     bo = drm_gem_object_lookup(dev, file_priv, handle);
> +     if (!bo)
> +             return -ENOENT;
> +
> +     obj_priv = bo->driver_private;
> +
> +     if (bo->size < width * height * 4) {
> +             DRM_ERROR("buffer is to small\n");
> +             return -ENOMEM;
> +     }

Refcount leak

> +
> +     if (dev_priv->cursor_needs_physical) {
> +             addr = dev->agp->base + obj_priv->gtt_offset;
> +     } else {
> +             addr = obj_priv->gtt_offset;
> +     }
> +
> +     intel_crtc->cursor_addr = addr;
> +     temp = 0;
> +     /* set the pipe for the cursor */
> +     temp |= (pipe << 28);
> +     temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
> +
> +     I915_WRITE(control, temp);
> +     I915_WRITE(base, addr);
> +
> +     return 0;
> +}


> +struct drm_framebuffer *
> +intel_framebuffer_create(struct drm_device *dev,
> +                      struct drm_mode_fb_cmd *mode_cmd,
> +                      struct drm_gem_object *obj)
> +{
> +     struct intel_framebuffer *intel_fb;
> +
> +     intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
> +     if (!intel_fb)
> +             return NULL;
> +
> +     if (!drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs))
> +             return NULL;
> +
> +     drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
> +
> +     intel_fb->obj = obj;
> +
> +     return &intel_fb->base;
> +}
> +
> +
> +static struct drm_framebuffer *
> +intel_user_framebuffer_create(struct drm_device *dev,
> +                           struct drm_file *filp,
> +                           struct drm_mode_fb_cmd *mode_cmd)
> +{
> +     struct drm_gem_object *obj;
> +
> +     obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
> +     if (!obj)
> +             return NULL;
> +
> +     return intel_framebuffer_create(dev, mode_cmd, obj);
> +}

I always find a lookup without unreference a bit surprising.  In this
case, it was correct for intel_framebuffer_create success, but if it
failed it would leak refcount.

> +static int intel_insert_new_fb(struct drm_device *dev, struct drm_file 
> *file_priv,
> +                             struct drm_framebuffer *fb, struct 
> drm_mode_fb_cmd *mode_cmd)
> +{
> +     struct intel_framebuffer *intel_fb;
> +     struct drm_gem_object *obj;
> +     struct drm_crtc *crtc;
> +
> +     intel_fb = to_intel_framebuffer(fb);
> +
> +     mutex_lock(&dev->struct_mutex);
> +     obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
> +     
> +     if (!obj) {
> +             mutex_unlock(&dev->struct_mutex);
> +             return -EINVAL;
> +     }
> +
> +     intel_fb->obj = obj;
> +     drm_gem_object_unreference(intel_fb->obj);
> +     drm_helper_mode_fill_fb_struct(fb, mode_cmd);
> +     mutex_unlock(&dev->struct_mutex);
> +

lookup is safe without struct_mutex, and cleans up this path a little.

> +void intel_modeset_init(struct drm_device *dev)
> +{
> +     int num_pipe;
> +     int i;
> +
> +     drm_mode_config_init(dev);
> +
> +     dev->mode_config.min_width = 0;
> +     dev->mode_config.min_height = 0;
> +
> +     dev->mode_config.funcs = (void *)&intel_mode_funcs;
> +
> +     if (IS_I965G(dev)) {
> +             dev->mode_config.max_width = 8192;
> +             dev->mode_config.max_height = 8192;
> +     } else {
> +             dev->mode_config.max_width = 2048;
> +             dev->mode_config.max_height = 2048;
> +     }
> +
> +     /* set memory base */
> +     if (IS_I9XX(dev))
> +             dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2);
> +     else
> +             dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
> +
> +     if (IS_MOBILE(dev) || IS_I9XX(dev))
> +             num_pipe = 2;
> +     else
> +             num_pipe = 1;
> +     DRM_DEBUG("%d display pipe%s available.\n",
> +               num_pipe, num_pipe > 1 ? "s" : "");
> +
> +     for (i = 0; i < num_pipe; i++) {
> +             intel_crtc_init(dev, i);
> +     }
> +
> +     intel_setup_outputs(dev);
> +
> +     /* setup fbs */
> +     //drm_initial_config(dev, false);

// comments

> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> new file mode 100644
> index 0000000..d4b2e03
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright (c) 2006 Dave Airlie <[EMAIL PROTECTED]>
> + * Copyright (c) 2007 Intel Corporation
> + *   Jesse Barnes <[EMAIL PROTECTED]>
> + */

Copyright without license

> diff --git a/drivers/gpu/drm/i915/intel_dvo.c 
> b/drivers/gpu/drm/i915/intel_dvo.c
> new file mode 100644
> index 0000000..18bab3a
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_dvo.c
> @@ -0,0 +1,499 @@
> +/*
> + * Copyright © 2006-2007 Intel Corporation
> + *
> + * 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 (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 NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS 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:
> + *   Eric Anholt <[EMAIL PROTECTED]>
> + */
> +/*
> + * Copyright 2006 Dave Airlie <[EMAIL PROTECTED]>
> + */

Are these copyrights not under the license above?  If so, what?

> +void intel_dvo_init(struct drm_device *dev)
> +{
> +     struct intel_output *intel_output;
> +     struct intel_dvo_device *dvo;
> +     struct intel_i2c_chan *i2cbus = NULL;
> +     int ret = 0;
> +     int i;
> +     int gpio_inited = 0;
> +     int encoder_type = DRM_MODE_ENCODER_NONE;
> +     intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
> +     if (!intel_output)
> +             return;
> +
> +     /* Set up the DDC bus */
> +     intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
> +     if (!intel_output->ddc_bus)
> +             goto free_intel;
> +
> +     /* Now, try to find a controller */
> +     for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
> +             struct drm_connector *connector = &intel_output->base;
> +             int gpio;
> +
> +             dvo = &intel_dvo_devices[i];
> +
> +             /* Allow the I2C driver info to specify the GPIO to be used in
> +              * special cases, but otherwise default to what's defined
> +              * in the spec.
> +              */
> +             if (dvo->gpio != 0)
> +                     gpio = dvo->gpio;
> +             else if (dvo->type == INTEL_DVO_CHIP_LVDS)
> +                     gpio = GPIOB;
> +             else
> +                     gpio = GPIOE;
> +
> +             /* Set up the I2C bus necessary for the chip we're probing.
> +              * It appears that everything is on GPIOE except for panels
> +              * on i830 laptops, which are on GPIOB (DVOA).
> +              */
> +             if (gpio_inited != gpio) {
> +                     if (i2cbus != NULL)
> +                             intel_i2c_destroy(i2cbus);
> +                     if (!(i2cbus = intel_i2c_create(dev, gpio,
> +                             gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
> +                             continue;
> +                     }
> +                     gpio_inited = gpio;
> +             }
> +
> +             if (dvo->dev_ops!= NULL)
> +                     ret = dvo->dev_ops->init(dvo, i2cbus);
> +             else
> +                     ret = false;
> +
> +             if (!ret)
> +                     continue;
> +
> +             intel_output->type = INTEL_OUTPUT_DVO;
> +             switch (dvo->type) {
> +             case INTEL_DVO_CHIP_TMDS:
> +               //                    connector = DRM_MODE_CONNECTOR_DVID;
> +                     drm_connector_init(dev, connector, 
> &intel_dvo_connector_funcs,
> +                                        DRM_MODE_CONNECTOR_DVII);
> +                     encoder_type = DRM_MODE_ENCODER_TMDS;
> +                     break;
> +             case INTEL_DVO_CHIP_LVDS:
> +               //                    connector = DRM_MODE_CONNECTOR_LVDS;
> +                     drm_connector_init(dev, connector, 
> &intel_dvo_connector_funcs,
> +                                        DRM_MODE_CONNECTOR_LVDS);
> +                     encoder_type = DRM_MODE_ENCODER_LVDS;
> +                     break;
> +             }

// comments

> diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
> new file mode 100644
> index 0000000..eb8c404
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_fb.c
> @@ -0,0 +1,908 @@
> +/*
> + * Copyright © 2007 David Airlie
> + *
> + * 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 (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 NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS 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:
> + *     David Airlie
> + */
> +    /*
> +     *  Modularization
> +     */

Unclear comment

> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/mm.h>
> +#include <linux/tty.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/fb.h>
> +#include <linux/init.h>
> +
> +#include "drmP.h"
> +#include "drm.h"
> +#include "drm_crtc.h"
> +#include "intel_drv.h"
> +#include "i915_drm.h"
> +#include "i915_drv.h"
> +
> +struct intelfb_par {
> +     struct drm_device *dev;
> +     struct drm_display_mode *our_mode;
> +     struct intel_framebuffer *intel_fb;
> +     int crtc_count;
> +     /* crtc currently bound to this */
> +     uint32_t crtc_ids[2];
> +};
> +/*
> +static int
> +var_to_refresh(const struct fb_var_screeninfo *var)
> +{
> +     int xtot = var->xres + var->left_margin + var->right_margin +
> +             var->hsync_len;
> +     int ytot = var->yres + var->upper_margin + var->lower_margin +
> +             var->vsync_len;
> +
> +     return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot;
> +}*/

Does this have any reason to live?

> +static struct fb_ops intelfb_ops = {
> +     .owner = THIS_MODULE,
> +     //.fb_open = intelfb_open,
> +     //.fb_read = intelfb_read,
> +     //.fb_write = intelfb_write,
> +     //.fb_release = intelfb_release,
> +     //.fb_ioctl = intelfb_ioctl,

// comments

> +     .fb_check_var = intelfb_check_var,
> +     .fb_set_par = intelfb_set_par,
> +     .fb_setcolreg = intelfb_setcolreg,
> +     .fb_fillrect = cfb_fillrect,
> +     .fb_copyarea = cfb_copyarea, //intelfb_copyarea,
> +     .fb_imageblit = cfb_imageblit, //intelfb_imageblit,
> +     .fb_pan_display = intelfb_pan_display,
> +     .fb_blank = intelfb_blank,
> +};

> +MODULE_LICENSE("GPL");

Should this be "GPL and additional rights", or is the license header at
the top of the file wrong?

> diff --git a/drivers/gpu/drm/i915/intel_i2c.c 
> b/drivers/gpu/drm/i915/intel_i2c.c
> new file mode 100644
> index 0000000..efcbf65
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright © 2006-2007 Intel Corporation
> + *
> + * 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 (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 NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS 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:
> + *   Eric Anholt <[EMAIL PROTECTED]>
> + */
> +/*
> + * Copyright (c) 2006 Dave Airlie <[EMAIL PROTECTED]>
> + *   Jesse Barnes <[EMAIL PROTECTED]>
> + */

Are these copyrights not under the license above?  If so, what?

> diff --git a/drivers/gpu/drm/i915/intel_modes.c 
> b/drivers/gpu/drm/i915/intel_modes.c
> new file mode 100644
> index 0000000..79be357
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_modes.c
> @@ -0,0 +1,61 @@
> +/*
> + * Copyright (c) 2007 Dave Airlie <[EMAIL PROTECTED]>
> + * Copyright (c) 2007 Intel Corporation
> + *   Jesse Barnes <[EMAIL PROTECTED]>
> + */

License?

> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c 
> b/drivers/gpu/drm/i915/intel_sdvo.c
> new file mode 100644
> index 0000000..abd889f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -0,0 +1,1106 @@
> +/*
> + * Copyright © 2006-2007 Intel Corporation
> + *
> + * 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 (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 NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS 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:
> + *   Eric Anholt <[EMAIL PROTECTED]>
> + */
> +/*
> + * Copyright 2006 Dave Airlie <[EMAIL PROTECTED]>
> + *   Jesse Barnes <[EMAIL PROTECTED]>
> + */

Are these copyrights not under the license above?  If so, what?

> +static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
> +                              u8 *ch)
> +{
> +     struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> +     u8 out_buf[2];
> +     u8 buf[2];
> +     int ret;
> +
> +     struct i2c_msg msgs[] = {
> +             { 
> +                     .addr = sdvo_priv->i2c_bus->slave_addr,
> +                     .flags = 0,
> +                     .len = 1,
> +                     .buf = out_buf,
> +             }, 
> +             {
> +                     .addr = sdvo_priv->i2c_bus->slave_addr,
> +                     .flags = I2C_M_RD,
> +                     .len = 1,
> +                     .buf = buf,
> +             }
> +     };
> +
> +     out_buf[0] = addr;
> +     out_buf[1] = 0;
> +
> +     if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
> +     {
> +//           DRM_DEBUG("got back from addr %02X = %02x\n", out_buf[0], 
> buf[0]); 

// comments

> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> new file mode 100644
> index 0000000..cb1255e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_tv.c

> +/**
> + * Detects TV presence by checking for load.
> + *
> + * Requires that the current pipe's DPLL is active.
> +
> + * \return true if TV is connected.
> + * \return false if TV is disconnected.
> + */
> +static int
> +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output 
> *intel_output)
> +{
> +     struct drm_encoder *encoder = &intel_output->enc;
> +     struct drm_device *dev = encoder->dev;
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     u32 pipeastat, pipeastat_save;
> +     u32 tv_ctl, save_tv_ctl;
> +     u32 tv_dac, save_tv_dac;
> +     int type = DRM_MODE_CONNECTOR_Unknown;
> +
> +     tv_dac = I915_READ(TV_DAC);
> +
> +     /* Disable TV interrupts around load detect or we'll recurse */
> +     pipeastat = I915_READ(PIPEASTAT);
> +     pipeastat_save = pipeastat;
> +     pipeastat &= ~PIPE_HOTPLUG_INTERRUPT_ENABLE;
> +     pipeastat &= ~PIPE_HOTPLUG_TV_INTERRUPT_ENABLE;
> +     I915_WRITE(PIPEASTAT, pipeastat | PIPE_HOTPLUG_TV_INTERRUPT_STATUS |
> +                PIPE_HOTPLUG_INTERRUPT_STATUS);
> +
> +     /*
> +      * Detect TV by polling)
> +      */
> +     if (intel_output->load_detect_temp) {
> +             /* TV not currently running, prod it with destructive detect */
> +             save_tv_dac = tv_dac;
> +             tv_ctl = I915_READ(TV_CTL);
> +             save_tv_ctl = tv_ctl;
> +             tv_ctl &= ~TV_ENC_ENABLE;
> +             tv_ctl &= ~TV_TEST_MODE_MASK;
> +             tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
> +             tv_dac &= ~TVDAC_SENSE_MASK;
> +             tv_dac |= (TVDAC_STATE_CHG_EN |
> +                        TVDAC_A_SENSE_CTL |
> +                        TVDAC_B_SENSE_CTL |
> +                        TVDAC_C_SENSE_CTL |
> +                        DAC_CTL_OVERRIDE |
> +                        DAC_A_0_7_V |
> +                        DAC_B_0_7_V |
> +                        DAC_C_0_7_V);
> +             I915_WRITE(TV_CTL, tv_ctl);
> +             I915_WRITE(TV_DAC, tv_dac);
> +             intel_wait_for_vblank(dev);
> +             tv_dac = I915_READ(TV_DAC);
> +             I915_WRITE(TV_DAC, save_tv_dac);
> +             I915_WRITE(TV_CTL, save_tv_ctl);
> +     }
> +     /*
> +      *  A B C
> +      *  0 1 1 Composite
> +      *  1 0 X svideo
> +      *  0 0 0 Component
> +      */
> +     if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
> +             DRM_DEBUG("Detected Composite TV connection\n");
> +             type = DRM_MODE_CONNECTOR_Composite;
> +     } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
> +             DRM_DEBUG("Detected S-Video TV connection\n");
> +             type = DRM_MODE_CONNECTOR_SVIDEO;
> +     } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
> +             DRM_DEBUG("Detected Component TV connection\n");
> +             type = DRM_MODE_CONNECTOR_Component;
> +     } else {
> +             DRM_DEBUG("No TV connection detected\n");
> +             type = -1;
> +     }
> +
> +     /* Restore interrupt config */
> +     I915_WRITE(PIPEASTAT, pipeastat_save | PIPE_HOTPLUG_TV_INTERRUPT_STATUS 
> |
> +                PIPE_HOTPLUG_INTERRUPT_STATUS);
> +
> +     return type;
> +}

PIPESTAT whacking without being protected by the lock.  This should
probably go directly in i915_irq.c (would we ever not be interested in
the hotplug interrupts, or be concerned about the rate they come in in
that case?), or otherwise use the pipestat update function that we've
got now.

-- 
Eric Anholt
[EMAIL PROTECTED]                         [EMAIL PROTECTED]


Attachment: signature.asc
Description: This is a digitally signed message part

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to