Author: dumbbell
Date: Tue Mar  8 20:33:02 2016
New Revision: 296548
URL: https://svnweb.freebsd.org/changeset/base/296548

Log:
  drm/i915: Update to match Linux 3.8.13
  
  This update brings initial support for Haswell GPUs.
  
  Tested by:    Many users of FreeBSD, PC-BSD and HardenedBSD
  Relnotes:     yes
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D5554

Added:
  head/sys/dev/drm2/drm_mem_util.h   (contents, props changed)
  head/sys/dev/drm2/i915/dvo.h   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_ch7017.c   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_ch7xxx.c   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_ivch.c   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_ns2501.c   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_sil164.c   (contents, props changed)
  head/sys/dev/drm2/i915/dvo_tfp410.c   (contents, props changed)
  head/sys/dev/drm2/i915/intel_acpi.c   (contents, props changed)
  head/sys/dev/drm2/i915/intel_dvo.c   (contents, props changed)
Modified:
  head/sys/dev/agp/agp_i810.c
  head/sys/dev/agp/agp_i810.h
  head/sys/dev/drm2/drmP.h
  head/sys/dev/drm2/drm_atomic.h
  head/sys/dev/drm2/drm_dp_iic_helper.c
  head/sys/dev/drm2/drm_drv.c
  head/sys/dev/drm2/drm_linux_list.h
  head/sys/dev/drm2/drm_os_freebsd.c
  head/sys/dev/drm2/drm_os_freebsd.h
  head/sys/dev/drm2/drm_pciids.h
  head/sys/dev/drm2/i915/i915_debug.c
  head/sys/dev/drm2/i915/i915_dma.c
  head/sys/dev/drm2/i915/i915_drm.h
  head/sys/dev/drm2/i915/i915_drv.c
  head/sys/dev/drm2/i915/i915_drv.h
  head/sys/dev/drm2/i915/i915_gem.c
  head/sys/dev/drm2/i915/i915_gem_context.c
  head/sys/dev/drm2/i915/i915_gem_evict.c
  head/sys/dev/drm2/i915/i915_gem_execbuffer.c
  head/sys/dev/drm2/i915/i915_gem_gtt.c
  head/sys/dev/drm2/i915/i915_gem_stolen.c
  head/sys/dev/drm2/i915/i915_gem_tiling.c
  head/sys/dev/drm2/i915/i915_irq.c
  head/sys/dev/drm2/i915/i915_reg.h
  head/sys/dev/drm2/i915/i915_suspend.c
  head/sys/dev/drm2/i915/intel_bios.c
  head/sys/dev/drm2/i915/intel_bios.h
  head/sys/dev/drm2/i915/intel_crt.c
  head/sys/dev/drm2/i915/intel_ddi.c
  head/sys/dev/drm2/i915/intel_display.c
  head/sys/dev/drm2/i915/intel_dp.c
  head/sys/dev/drm2/i915/intel_drv.h
  head/sys/dev/drm2/i915/intel_fb.c
  head/sys/dev/drm2/i915/intel_hdmi.c
  head/sys/dev/drm2/i915/intel_iic.c
  head/sys/dev/drm2/i915/intel_lvds.c
  head/sys/dev/drm2/i915/intel_modes.c
  head/sys/dev/drm2/i915/intel_opregion.c
  head/sys/dev/drm2/i915/intel_overlay.c
  head/sys/dev/drm2/i915/intel_panel.c
  head/sys/dev/drm2/i915/intel_pm.c
  head/sys/dev/drm2/i915/intel_ringbuffer.c
  head/sys/dev/drm2/i915/intel_ringbuffer.h
  head/sys/dev/drm2/i915/intel_sdvo.c
  head/sys/dev/drm2/i915/intel_sprite.c
  head/sys/dev/drm2/i915/intel_tv.c
  head/sys/modules/drm2/i915kms/Makefile

Modified: head/sys/dev/agp/agp_i810.c
==============================================================================
--- head/sys/dev/agp/agp_i810.c Tue Mar  8 20:24:12 2016        (r296547)
+++ head/sys/dev/agp/agp_i810.c Tue Mar  8 20:33:02 2016        (r296548)
@@ -250,6 +250,10 @@ struct agp_i810_driver {
        void (*chipset_flush)(device_t);
 };
 
+static struct {
+       struct intel_gtt base;
+} intel_private;
+
 static const struct agp_i810_driver agp_i810_i810_driver = {
        .chiptype = CHIP_I810,
        .gen = 1,
@@ -526,6 +530,29 @@ static const struct agp_i810_driver agp_
        .chipset_flush = agp_i810_chipset_flush,
 };
 
+static const struct agp_i810_driver agp_i810_valleyview_driver = {
+       .chiptype = CHIP_SB,
+       .gen = 7,
+       .busdma_addr_mask_sz = 40,
+       .res_spec = agp_g4x_res_spec,
+       .check_active = agp_sb_check_active,
+       .set_desc = agp_i810_set_desc,
+       .dump_regs = agp_sb_dump_regs,
+       .get_stolen_size = agp_sb_get_stolen_size,
+       .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
+       .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
+       .install_gatt = agp_g4x_install_gatt,
+       .deinstall_gatt = agp_i830_deinstall_gatt,
+       .write_gtt = agp_sb_write_gtt,
+       .install_gtt_pte = agp_sb_install_gtt_pte,
+       .read_gtt_pte = agp_g4x_read_gtt_pte,
+       .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
+       .set_aperture = agp_i915_set_aperture,
+       .chipset_flush_setup = agp_i810_chipset_flush_setup,
+       .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
+       .chipset_flush = agp_i810_chipset_flush,
+};
+
 /* For adding new devices, devid is the id of the graphics controller
  * (pci:0:2:0, for example).  The placeholder (usually at pci:0:2:1) for the
  * second head should never be added.  The bridge_offset is the offset to
@@ -763,40 +790,200 @@ static const struct agp_i810_match {
        },
        {
                .devid = 0x04028086,
-               .name = "Haswell desktop GT1",
+               .name = "Haswell GT1 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x04068086,
+               .name = "Haswell GT1 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x040A8086,
+               .name = "Haswell GT1 server",
                .driver = &agp_i810_hsw_driver
        },
        {
                .devid = 0x04128086,
-               .name = "Haswell desktop GT2",
+               .name = "Haswell GT2 desktop",
                .driver = &agp_i810_hsw_driver
        },
        {
-               .devid = 0x040a8086,
-               .name = "Haswell server GT1",
+               .devid = 0x04168086,
+               .name = "Haswell GT2 mobile",
                .driver = &agp_i810_hsw_driver
        },
        {
-               .devid = 0x041a8086,
-               .name = "Haswell server GT2",
+               .devid = 0x041A8086,
+               .name = "Haswell GT2 server",
                .driver = &agp_i810_hsw_driver
        },
        {
-               .devid = 0x04068086,
-               .name = "Haswell mobile GT1",
+               .devid = 0x04228086,
+               .name = "Haswell GT2 desktop",
                .driver = &agp_i810_hsw_driver
        },
        {
-               .devid = 0x04168086,
-               .name = "Haswell mobile GT2",
+               .devid = 0x04268086,
+               .name = "Haswell GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x042A8086,
+               .name = "Haswell GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A028086,
+               .name = "Haswell ULT GT1 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A068086,
+               .name = "Haswell ULT GT1 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A0A8086,
+               .name = "Haswell ULT GT1 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A128086,
+               .name = "Haswell ULT GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A168086,
+               .name = "Haswell ULT GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A1A8086,
+               .name = "Haswell ULT GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A228086,
+               .name = "Haswell ULT GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A268086,
+               .name = "Haswell ULT GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0A2A8086,
+               .name = "Haswell ULT GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C028086,
+               .name = "Haswell SDV GT1 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C068086,
+               .name = "Haswell SDV GT1 mobile",
                .driver = &agp_i810_hsw_driver
        },
        {
-               .devid = 0x0c168086,
-               .name = "Haswell SDV",
+               .devid = 0x0C0A8086,
+               .name = "Haswell SDV GT1 server",
                .driver = &agp_i810_hsw_driver
        },
        {
+               .devid = 0x0C128086,
+               .name = "Haswell SDV GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C168086,
+               .name = "Haswell SDV GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C1A8086,
+               .name = "Haswell SDV GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C228086,
+               .name = "Haswell SDV GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C268086,
+               .name = "Haswell SDV GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0C2A8086,
+               .name = "Haswell SDV GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D028086,
+               .name = "Haswell CRW GT1 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D068086,
+               .name = "Haswell CRW GT1 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D0A8086,
+               .name = "Haswell CRW GT1 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D128086,
+               .name = "Haswell CRW GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D168086,
+               .name = "Haswell CRW GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D1A8086,
+               .name = "Haswell CRW GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D228086,
+               .name = "Haswell CRW GT2 desktop",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D268086,
+               .name = "Haswell CRW GT2 mobile",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x0D2A8086,
+               .name = "Haswell CRW GT2 server",
+               .driver = &agp_i810_hsw_driver
+       },
+       {
+               .devid = 0x01558086,
+               .name = "Valleyview (desktop)",
+               .driver = &agp_i810_valleyview_driver
+       },
+       {
+               .devid = 0x01578086,
+               .name = "Valleyview (mobile)",
+               .driver = &agp_i810_valleyview_driver
+       },
+       {
+               .devid = 0x0F308086,
+               .name = "Valleyview (mobile)",
+               .driver = &agp_i810_valleyview_driver
+       },
+       {
                .devid = 0,
        }
 };
@@ -2285,6 +2472,10 @@ agp_intel_gtt_get(device_t dev)
        res.gtt_mappable_entries = sc->gtt_mappable_entries;
        res.do_idle_maps = 0;
        res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
+       if (sc->agp.as_aperture != NULL)
+               res.gma_bus_addr = rman_get_start(sc->agp.as_aperture);
+       else
+               res.gma_bus_addr = 0;
        return (res);
 }
 
@@ -2588,11 +2779,12 @@ intel_gtt_insert_pages(u_int first_entry
            pages, flags);
 }
 
-struct intel_gtt
+struct intel_gtt *
 intel_gtt_get(void)
 {
 
-       return (agp_intel_gtt_get(intel_agp));
+       intel_private.base = agp_intel_gtt_get(intel_agp);
+       return (&intel_private.base);
 }
 
 int

Modified: head/sys/dev/agp/agp_i810.h
==============================================================================
--- head/sys/dev/agp/agp_i810.h Tue Mar  8 20:24:12 2016        (r296547)
+++ head/sys/dev/agp/agp_i810.h Tue Mar  8 20:33:02 2016        (r296548)
@@ -33,6 +33,7 @@
 #define        AGP_AGP_I810_H
 
 #include <sys/param.h>
+#include <sys/rman.h>
 #include <sys/sglist.h>
 
 #include <vm/vm.h>
@@ -51,24 +52,23 @@
 
 struct intel_gtt {
        /* Size of memory reserved for graphics by the BIOS */
-       u_int stolen_size;
+       unsigned int stolen_size;
        /* Total number of gtt entries. */
-       u_int gtt_total_entries;
-       /*
-        * Part of the gtt that is mappable by the cpu, for those
-        * chips where this is not the full gtt.
-        */
-       u_int gtt_mappable_entries;
-
-       /*
-        * Always false.
-        */
-       u_int do_idle_maps;
-       
-       /*
-        * Share the scratch page dma with ppgtts.
-        */
+       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;
+       /* Whether i915 needs to use the dmar apis or not. */
+       unsigned int needs_dmar : 1;
+       /* Whether we idle the gpu before mapping/unmapping */
+       unsigned int do_idle_maps : 1;
+       /* Share the scratch page dma with ppgtts. */
        vm_paddr_t scratch_page_dma;
+       vm_page_t scratch_page;
+       /* for ppgtt PDE access */
+       uint32_t *gtt;
+       /* needed for ioremap in drm/i915 */
+       bus_addr_t gma_bus_addr;
 };
 
 struct intel_gtt agp_intel_gtt_get(device_t dev);
@@ -83,7 +83,7 @@ void agp_intel_gtt_insert_sg_entries(dev
 void agp_intel_gtt_insert_pages(device_t dev, u_int first_entry,
     u_int num_entries, vm_page_t *pages, u_int flags);
 
-struct intel_gtt intel_gtt_get(void);
+struct intel_gtt *intel_gtt_get(void);
 int intel_gtt_chipset_flush(void);
 void intel_gtt_unmap_memory(struct sglist *sg_list);
 void intel_gtt_clear_range(u_int first_entry, u_int num_entries);

Modified: head/sys/dev/drm2/drmP.h
==============================================================================
--- head/sys/dev/drm2/drmP.h    Tue Mar  8 20:24:12 2016        (r296547)
+++ head/sys/dev/drm2/drmP.h    Tue Mar  8 20:33:02 2016        (r296548)
@@ -238,7 +238,6 @@ struct drm_device;
                        __func__ , ##__VA_ARGS__);                      \
 } while (0)
 
-
 /*@}*/
 
 /***********************************************************************/
@@ -700,6 +699,8 @@ struct drm_driver {
        void (*postclose) (struct drm_device *, struct drm_file *);
        void (*lastclose) (struct drm_device *);
        int (*unload) (struct drm_device *);
+       int (*suspend) (struct drm_device *, pm_message_t state);
+       int (*resume) (struct drm_device *);
        int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file 
*file_priv);
        int (*dma_quiescent) (struct drm_device *);
        int (*context_dtor) (struct drm_device *dev, int context);
@@ -1118,7 +1119,7 @@ struct drm_device {
        char busid_str[128];
        int modesetting;
 
-       drm_pci_id_list_t *id_entry;    /* PCI ID, name, and chipset private */
+       const drm_pci_id_list_t *id_entry;      /* PCI ID, name, and chipset 
private */
 };
 
 #define DRM_SWITCH_POWER_ON 0
@@ -1581,6 +1582,8 @@ static __inline__ void drm_core_dropmap(
 {
 }
 
+#include <dev/drm2/drm_mem_util.h>
+
 extern int drm_fill_in_dev(struct drm_device *dev,
                           struct drm_driver *driver);
 extern void drm_cancel_fill_in_dev(struct drm_device *dev);
@@ -1758,9 +1761,11 @@ struct dmi_system_id {
 bool dmi_check_system(const struct dmi_system_id *);
 
 /* Device setup support (drm_drv.c) */
-int    drm_probe_helper(device_t kdev, drm_pci_id_list_t *idlist);
-int    drm_attach_helper(device_t kdev, drm_pci_id_list_t *idlist,
+int    drm_probe_helper(device_t kdev, const drm_pci_id_list_t *idlist);
+int    drm_attach_helper(device_t kdev, const drm_pci_id_list_t *idlist,
            struct drm_driver *driver);
+int    drm_generic_suspend(device_t kdev);
+int    drm_generic_resume(device_t kdev);
 int    drm_generic_detach(device_t kdev);
 
 void drm_event_wakeup(struct drm_pending_event *e);

Modified: head/sys/dev/drm2/drm_atomic.h
==============================================================================
--- head/sys/dev/drm2/drm_atomic.h      Tue Mar  8 20:24:12 2016        
(r296547)
+++ head/sys/dev/drm2/drm_atomic.h      Tue Mar  8 20:33:02 2016        
(r296548)
@@ -39,8 +39,8 @@ typedef uint64_t      atomic64_t;
 #define        NB_BITS_PER_LONG                (sizeof(long) * NBBY)
 #define        BITS_TO_LONGS(x)                howmany(x, NB_BITS_PER_LONG)
 
-#define        atomic_read(p)                  (*(volatile u_int *)(p))
-#define        atomic_set(p, v)                do { *(u_int *)(p) = (v); } 
while (0)
+#define        atomic_read(p)                  atomic_load_acq_int(p)
+#define        atomic_set(p, v)                atomic_store_rel_int(p, v)
 
 #define        atomic64_read(p)                atomic_load_acq_64(p)
 #define        atomic64_set(p, v)              atomic_store_rel_64(p, v)
@@ -78,6 +78,9 @@ typedef uint64_t      atomic64_t;
 #define        cmpxchg(ptr, old, new) \
     (atomic_cmpset_int((volatile u_int *)(ptr),(old),(new)) ? (old) : (0))
 
+#define        atomic_inc_not_zero(p)          atomic_inc(p)
+#define        atomic_clear_mask(b, p)         atomic_clear_int((p), (b))
+
 static __inline u_long
 find_first_zero_bit(const u_long *p, u_long max)
 {

Modified: head/sys/dev/drm2/drm_dp_iic_helper.c
==============================================================================
--- head/sys/dev/drm2/drm_dp_iic_helper.c       Tue Mar  8 20:24:12 2016        
(r296547)
+++ head/sys/dev/drm2/drm_dp_iic_helper.c       Tue Mar  8 20:33:02 2016        
(r296548)
@@ -149,7 +149,7 @@ iic_dp_aux_xfer(device_t idev, struct ii
                buf = msgs[m].buf;
                reading = (msgs[m].flags & IIC_M_RD) != 0;
                ret = iic_dp_aux_address(idev, msgs[m].slave >> 1, reading);
-               if (ret != 0)
+               if (ret < 0)
                        break;
                if (reading) {
                        for (b = 0; b < len; b++) {
@@ -160,7 +160,7 @@ iic_dp_aux_xfer(device_t idev, struct ii
                } else {
                        for (b = 0; b < len; b++) {
                                ret = iic_dp_aux_put_byte(idev, buf[b]);
-                               if (ret != 0)
+                               if (ret < 0)
                                        break;
                        }
                }

Modified: head/sys/dev/drm2/drm_drv.c
==============================================================================
--- head/sys/dev/drm2/drm_drv.c Tue Mar  8 20:24:12 2016        (r296547)
+++ head/sys/dev/drm2/drm_drv.c Tue Mar  8 20:33:02 2016        (r296548)
@@ -470,6 +470,14 @@ int drm_ioctl(struct cdev *kdev, u_long 
 
       err_i1:
        atomic_dec(&dev->ioctl_count);
+       if (retcode == -ERESTARTSYS) {
+               /*
+                * FIXME: Find where in i915 ERESTARTSYS should be
+                * converted to EINTR.
+                */
+               DRM_DEBUG("ret = %d -> %d\n", retcode, -EINTR);
+               retcode = -EINTR;
+       }
        if (retcode)
                DRM_DEBUG("ret = %d\n", retcode);
        if (retcode != 0 &&

Modified: head/sys/dev/drm2/drm_linux_list.h
==============================================================================
--- head/sys/dev/drm2/drm_linux_list.h  Tue Mar  8 20:24:12 2016        
(r296547)
+++ head/sys/dev/drm2/drm_linux_list.h  Tue Mar  8 20:33:02 2016        
(r296548)
@@ -40,7 +40,6 @@ struct list_head {
 };
 
 #define list_entry(ptr, type, member) container_of(ptr,type,member)
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
 
 static __inline__ void
 INIT_LIST_HEAD(struct list_head *head) {
@@ -179,4 +178,123 @@ list_splice(const struct list_head *list
 void drm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv,
     struct list_head *a, struct list_head *b));
 
+/* hlist, copied from sys/dev/ofed/linux/list.h */
+
+struct hlist_head {
+       struct hlist_node *first;
+};
+
+struct hlist_node {
+       struct hlist_node *next, **pprev;
+};
+
+#define        HLIST_HEAD_INIT { }
+#define        HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT
+#define        INIT_HLIST_HEAD(head) (head)->first = NULL
+#define        INIT_HLIST_NODE(node)                                           
\
+do {                                                                   \
+       (node)->next = NULL;                                            \
+       (node)->pprev = NULL;                                           \
+} while (0)
+
+static inline int
+hlist_unhashed(const struct hlist_node *h)
+{
+
+       return !h->pprev;
+}
+
+static inline int
+hlist_empty(const struct hlist_head *h)
+{
+
+       return !h->first;
+}
+
+static inline void
+hlist_del(struct hlist_node *n)
+{
+
+        if (n->next)
+                n->next->pprev = n->pprev;
+        *n->pprev = n->next;
+}
+
+static inline void
+hlist_del_init(struct hlist_node *n)
+{
+
+       if (hlist_unhashed(n))
+               return;
+       hlist_del(n);
+       INIT_HLIST_NODE(n);
+}
+
+static inline void
+hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+
+       n->next = h->first;
+       if (h->first)
+               h->first->pprev = &n->next;
+       h->first = n;
+       n->pprev = &h->first;
+}
+
+static inline void
+hlist_add_before(struct hlist_node *n, struct hlist_node *next)
+{
+
+       n->pprev = next->pprev;
+       n->next = next;
+       next->pprev = &n->next;
+       *(n->pprev) = n;
+}
+
+static inline void
+hlist_add_after(struct hlist_node *n, struct hlist_node *next)
+{
+
+       next->next = n->next;
+       n->next = next;
+       next->pprev = &n->next;
+       if (next->next)
+               next->next->pprev = &next->next;
+}
+
+static inline void
+hlist_move_list(struct hlist_head *old, struct hlist_head *new)
+{
+
+       new->first = old->first;
+       if (new->first)
+               new->first->pprev = &new->first;
+       old->first = NULL;
+}
+
+#define        hlist_entry(ptr, type, field)   container_of(ptr, type, field)
+
+#define        hlist_for_each(p, head)                                         
\
+       for (p = (head)->first; p; p = p->next)
+
+#define        hlist_for_each_safe(p, n, head)                                 
\
+       for (p = (head)->first; p && ({ n = p->next; 1; }); p = n)
+
+#define        hlist_for_each_entry(tp, p, head, field)                        
\
+       for (p = (head)->first;                                         \
+           p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
+
+#define hlist_for_each_entry_continue(tp, p, field)                    \
+       for (p = (p)->next;                                             \
+           p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
+
+#define        hlist_for_each_entry_from(tp, p, field)                         
\
+       for (; p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
+
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
+       for (pos = (head)->first;                                        \
+            (pos) != 0 && ({ n = (pos)->next; \
+                tpos = hlist_entry((pos), typeof(*(tpos)), member); 1;}); \
+            pos = (n))
+
 #endif /* _DRM_LINUX_LIST_H_ */

Added: head/sys/dev/drm2/drm_mem_util.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/dev/drm2/drm_mem_util.h    Tue Mar  8 20:33:02 2016        
(r296548)
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2008 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:
+ *     Jesse Barnes <jbar...@virtuousgeek.org>
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef _DRM_MEM_UTIL_H_
+#define _DRM_MEM_UTIL_H_
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
+{
+       if (size != 0 && nmemb > SIZE_MAX / size)
+               return NULL;
+
+       return malloc(nmemb * size, DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
+}
+
+/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. 
*/
+static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+{
+       if (size != 0 && nmemb > SIZE_MAX / size)
+               return NULL;
+
+       return malloc(nmemb * size, DRM_MEM_DRIVER, M_NOWAIT);
+}
+
+static __inline void drm_free_large(void *ptr)
+{
+       free(ptr, DRM_MEM_DRIVER);
+}
+
+#endif

Modified: head/sys/dev/drm2/drm_os_freebsd.c
==============================================================================
--- head/sys/dev/drm2/drm_os_freebsd.c  Tue Mar  8 20:24:12 2016        
(r296547)
+++ head/sys/dev/drm2/drm_os_freebsd.c  Tue Mar  8 20:33:02 2016        
(r296548)
@@ -67,8 +67,27 @@ ns_to_timeval(const int64_t nsec)
         return (tv);
 }
 
-static drm_pci_id_list_t *
-drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist)
+/* Copied from OFED. */
+unsigned long drm_linux_timer_hz_mask;
+
+static void
+drm_linux_timer_init(void *arg)
+{
+
+        /*
+         * Compute an internal HZ value which can divide 2**32 to
+         * avoid timer rounding problems when the tick value wraps
+         * around 2**32:
+         */
+        drm_linux_timer_hz_mask = 1;
+        while (drm_linux_timer_hz_mask < (unsigned long)hz)
+                drm_linux_timer_hz_mask *= 2;
+        drm_linux_timer_hz_mask--;
+}
+SYSINIT(drm_linux_timer, SI_SUB_DRIVERS, SI_ORDER_FIRST, drm_linux_timer_init, 
NULL);
+
+static const drm_pci_id_list_t *
+drm_find_description(int vendor, int device, const drm_pci_id_list_t *idlist)
 {
        int i = 0;
 
@@ -87,9 +106,9 @@ drm_find_description(int vendor, int dev
  * method.
  */
 int
-drm_probe_helper(device_t kdev, drm_pci_id_list_t *idlist)
+drm_probe_helper(device_t kdev, const drm_pci_id_list_t *idlist)
 {
-       drm_pci_id_list_t *id_entry;
+       const drm_pci_id_list_t *id_entry;
        int vendor, device;
 
        vendor = pci_get_vendor(kdev);
@@ -118,7 +137,7 @@ drm_probe_helper(device_t kdev, drm_pci_
  * method.
  */
 int
-drm_attach_helper(device_t kdev, drm_pci_id_list_t *idlist,
+drm_attach_helper(device_t kdev, const drm_pci_id_list_t *idlist,
     struct drm_driver *driver)
 {
        struct drm_device *dev;
@@ -137,6 +156,55 @@ drm_attach_helper(device_t kdev, drm_pci
 }
 
 int
+drm_generic_suspend(device_t kdev)
+{
+       struct drm_device *dev;
+       int error;
+
+       DRM_DEBUG_KMS("Starting suspend\n");
+
+       dev = device_get_softc(kdev);
+       if (dev->driver->suspend) {
+               pm_message_t state;
+
+               state.event = PM_EVENT_SUSPEND;
+               error = -dev->driver->suspend(dev, state);
+               if (error)
+                       goto out;
+       }
+
+       error = bus_generic_suspend(kdev);
+
+out:
+       DRM_DEBUG_KMS("Finished suspend: %d\n", error);
+
+       return error;
+}
+
+int
+drm_generic_resume(device_t kdev)
+{
+       struct drm_device *dev;
+       int error;
+
+       DRM_DEBUG_KMS("Starting resume\n");
+
+       dev = device_get_softc(kdev);
+       if (dev->driver->resume) {
+               error = -dev->driver->resume(dev);
+               if (error)
+                       goto out;
+       }
+
+       error = bus_generic_resume(kdev);
+
+out:
+       DRM_DEBUG_KMS("Finished resume: %d\n", error);
+
+       return error;
+}
+
+int
 drm_generic_detach(device_t kdev)
 {
        struct drm_device *dev;
@@ -331,6 +399,42 @@ drm_clflush_virt_range(char *addr, unsig
 #endif
 }
 
+void
+hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
+    char *linebuf, size_t linebuflen, bool ascii __unused)
+{
+       int i, j, c;
+
+       i = j = 0;
+
+       while (i < len && j <= linebuflen) {
+               c = ((const char *)buf)[i];
+
+               if (i != 0) {
+                       if (i % rowsize == 0) {
+                               /* Newline required. */
+                               sprintf(linebuf + j, "\n");
+                               ++j;
+                       } else if (i % groupsize == 0) {
+                               /* Space required. */
+                               sprintf(linebuf + j, " ");
+                               ++j;
+                       }
+               }
+
+               if (j > linebuflen - 1)
+                       break;
+
+               sprintf(linebuf + j, "%02X", c);
+               j += 2;
+
+               ++i;
+       }
+
+       if (j <= linebuflen)
+               sprintf(linebuf + j, "\n");
+}
+
 #if DRM_LINUX
 
 #include <sys/sysproto.h>

Modified: head/sys/dev/drm2/drm_os_freebsd.h
==============================================================================
--- head/sys/dev/drm2/drm_os_freebsd.h  Tue Mar  8 20:24:12 2016        
(r296547)
+++ head/sys/dev/drm2/drm_os_freebsd.h  Tue Mar  8 20:33:02 2016        
(r296548)
@@ -10,6 +10,7 @@ __FBSDID("$FreeBSD$");
 #define        _DRM_OS_FREEBSD_H_
 
 #include <sys/fbio.h>
+#include <sys/smp.h>
 
 #if _BYTE_ORDER == _BIG_ENDIAN
 #define        __BIG_ENDIAN 4321
@@ -24,10 +25,22 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #ifndef __user
-#define __user
+#define        __user
 #endif
 #ifndef __iomem
-#define __iomem
+#define        __iomem
+#endif
+#ifndef __always_unused
+#define        __always_unused
+#endif
+#ifndef __must_check
+#define        __must_check
+#endif
+#ifndef __force
+#define        __force
+#endif
+#ifndef uninitialized_var
+#define        uninitialized_var(x) x
 #endif
 
 #define        cpu_to_le16(x)  htole16(x)
@@ -69,9 +82,23 @@ typedef void                 irqreturn_t;
 #define        __exit
 #define        __read_mostly
 
-#define        WARN_ON(cond)           KASSERT(!(cond), ("WARN ON: " #cond))
+#define        BUILD_BUG_ON(x)         CTASSERT(!(x))
+#define        BUILD_BUG_ON_NOT_POWER_OF_2(x)
+
+#ifndef WARN
+#define WARN(condition, format, ...) ({                                \
+       int __ret_warn_on = !!(condition);                      \
+       if (unlikely(__ret_warn_on))                            \
+       DRM_ERROR(format, ##__VA_ARGS__);                       \
+       unlikely(__ret_warn_on);                                \
+})
+#endif
+#define        WARN_ONCE(condition, format, ...)                       \
+       WARN(condition, format, ##__VA_ARGS__)
+#define        WARN_ON(cond)           WARN(cond, "WARN ON: " #cond)
 #define        WARN_ON_SMP(cond)       WARN_ON(cond)
-#define        BUG_ON(cond)            KASSERT(!(cond), ("BUG ON: " #cond))
+#define        BUG()                   panic("BUG")
+#define        BUG_ON(cond)            KASSERT(!(cond), ("BUG ON: " #cond " -> 
0x%jx", (uintmax_t)(cond)))
 #define        unlikely(x)            __builtin_expect(!!(x), 0)
 #define        likely(x)              __builtin_expect(!!(x), 1)
 #define        container_of(ptr, type, member) ({                      \
@@ -93,6 +120,15 @@ typedef void                        irqreturn_t;
 #define        DRM_UDELAY(udelay)      DELAY(udelay)
 #define        drm_msleep(x, msg)      pause((msg), ((int64_t)(x)) * hz / 1000)
 #define        DRM_MSLEEP(msecs)       drm_msleep((msecs), "drm_msleep")
+#define        get_seconds()           time_second
+
+#define ioread8(addr)          *(volatile uint8_t *)((char *)addr)
+#define ioread16(addr)         *(volatile uint16_t *)((char *)addr)
+#define ioread32(addr)         *(volatile uint32_t *)((char *)addr)
+
+#define iowrite8(data, addr)   *(volatile uint8_t *)((char *)addr) = data;
+#define iowrite16(data, addr)  *(volatile uint16_t *)((char *)addr) = data;
+#define iowrite32(data, addr)  *(volatile uint32_t *)((char *)addr) = data;
 
 #define        DRM_READ8(map, offset)                                          
\
        *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) +           \
@@ -127,12 +163,18 @@ typedef void                      irqreturn_t;
 #define        DRM_WRITEMEMORYBARRIER()        wmb()
 #define        DRM_MEMORYBARRIER()             mb()
 #define        smp_rmb()                       rmb()
+#define        smp_wmb()                       wmb()
 #define        smp_mb__before_atomic_inc()     mb()
 #define        smp_mb__after_atomic_inc()      mb()
+#define        barrier()                       __compiler_membar()
 
 #define        do_div(a, b)            ((a) /= (b))
 #define        div64_u64(a, b)         ((a) / (b))
 #define        lower_32_bits(n)        ((u32)(n))
+#define        upper_32_bits(n)        ((u32)(((n) >> 16) >> 16))
+
+#define        __set_bit(n, s)         set_bit((n), (s))
+#define        __clear_bit(n, s)       clear_bit((n), (s))
 
 #define min_t(type, x, y) ({                   \
        type __min1 = (x);                      \
@@ -148,6 +190,10 @@ typedef void                       irqreturn_t;
 #define        memcpy_fromio(a, b, c)  memcpy((a), (b), (c))
 #define        memcpy_toio(a, b, c)    memcpy((a), (b), (c))
 
+#define        VERIFY_READ     VM_PROT_READ
+#define        VERIFY_WRITE    VM_PROT_WRITE
+#define        access_ok(prot, p, l)   useracc((p), (l), (prot))
+
 /* XXXKIB what is the right code for the FreeBSD ? */
 /* kib@ used ENXIO here -- dumbbell@ */
 #define        EREMOTEIO       EIO
@@ -170,8 +216,10 @@ typedef void                       irqreturn_t;
 #define        PCI_VENDOR_ID_SONY              0x104d
 #define        PCI_VENDOR_ID_VIA               0x1106
 
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-#define        hweight32(i)    bitcount32(i)
+#define DIV_ROUND_UP(n,d)      (((n) + (d) - 1) / (d))
+#define        DIV_ROUND_CLOSEST(n,d)  (((n) + (d) / 2) / (d))
+#define        div_u64(n, d)           ((n) / (d))
+#define        hweight32(i)            bitcount32(i)
 
 static inline unsigned long
 roundup_pow_of_two(unsigned long x)
@@ -195,6 +243,8 @@ ror32(uint32_t word, unsigned int shift)
 }
 
 #define        IS_ALIGNED(x, y)        (((x) & ((y) - 1)) == 0)
+#define        round_down(x, y)        rounddown2((x), (y))
+#define        round_up(x, y)          roundup2((x), (y))
 #define        get_unaligned(ptr)                                              
\
        ({ __typeof__(*(ptr)) __tmp;                                    \
          memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
@@ -251,7 +301,9 @@ abs64(int64_t x)
 int64_t                timeval_to_ns(const struct timeval *tv);
 struct timeval ns_to_timeval(const int64_t nsec);
 
-#define PAGE_ALIGN(addr) round_page(addr)
+#define        PAGE_ALIGN(addr) round_page(addr)
+#define        page_to_phys(x) VM_PAGE_TO_PHYS(x)
+#define        offset_in_page(x) ((x) & PAGE_MASK)
 
 #define        drm_get_device_from_kdev(_kdev) (((struct drm_minor 
*)(_kdev)->si_drv1)->dev)
 
@@ -295,20 +347,193 @@ __get_user(size_t size, const void *ptr,
 }
 #define        get_user(x, ptr) __get_user(sizeof(*ptr), (ptr), &(x))
 
+static inline int
+__copy_to_user_inatomic(void __user *to, const void *from, unsigned n)
+{
+
+       return (copyout_nofault(from, to, n) != 0 ? n : 0);
+}
+#define        __copy_to_user_inatomic_nocache(to, from, n) \
+    __copy_to_user_inatomic((to), (from), (n))
+
+static inline unsigned long
+__copy_from_user_inatomic(void *to, const void __user *from,
+    unsigned long n)
+{
+
+       /*
+        * XXXKIB.  Equivalent Linux function is implemented using
+        * MOVNTI for aligned moves.  For unaligned head and tail,
+        * normal move is performed.  As such, it is not incorrect, if
+        * only somewhat slower, to use normal copyin.  All uses
+        * except shmem_pwrite_fast() have the destination mapped WC.
+        */
+       return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0));
+}
+#define        __copy_from_user_inatomic_nocache(to, from, n) \
+    __copy_from_user_inatomic((to), (from), (n))
+
+static inline int
+fault_in_multipages_readable(const char __user *uaddr, int size)
+{
+       char c;
+       int ret = 0;
+       const char __user *end = uaddr + size - 1;
+
+       if (unlikely(size == 0))
+               return ret;
+
+       while (uaddr <= end) {
+               ret = -copyin(uaddr, &c, 1);
+               if (ret != 0)
+                       return -EFAULT;
+               uaddr += PAGE_SIZE;
+       }
+
+       /* Check whether the range spilled into the next page. */
+       if (((unsigned long)uaddr & ~PAGE_MASK) ==
+                       ((unsigned long)end & ~PAGE_MASK)) {
+               ret = -copyin(end, &c, 1);
+       }
+
+       return ret;
+}
+
+static inline int
+fault_in_multipages_writeable(char __user *uaddr, int size)
+{
+       int ret = 0;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to