svn commit: r296548 - in head/sys: dev/agp dev/drm2 dev/drm2/i915 modules/drm2/i915kms
Jean-Sébastien Pédron
dumbbell at FreeBSD.org
Tue Mar 8 20:33:04 UTC 2016
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 <jbarnes at 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 ***
More information about the svn-src-all
mailing list