[PATCH 7/9] drm/vc4: Add support for drawing 3D frames.

2015-12-01 Thread Eric Anholt
The user submission is basically a pointer to a command list and a
pointer to uniforms.  We copy those in to the kernel, validate and
relocate them, and store the result in a GPU BO which we queue for
execution.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/Makefile   |   7 +
 drivers/gpu/drm/vc4/vc4_drv.c  |  15 +-
 drivers/gpu/drm/vc4/vc4_drv.h  | 192 +++
 drivers/gpu/drm/vc4/vc4_gem.c  | 640 ++
 drivers/gpu/drm/vc4/vc4_irq.c  | 210 
 drivers/gpu/drm/vc4/vc4_packet.h   | 399 ++
 drivers/gpu/drm/vc4/vc4_render_cl.c| 631 ++
 drivers/gpu/drm/vc4/vc4_trace.h|  63 +++
 drivers/gpu/drm/vc4/vc4_trace_points.c |  14 +
 drivers/gpu/drm/vc4/vc4_v3d.c  |  37 ++
 drivers/gpu/drm/vc4/vc4_validate.c | 955 +
 include/uapi/drm/vc4_drm.h | 141 +
 12 files changed, 3303 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_gem.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_irq.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_packet.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_render_cl.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace_points.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index e87a6f2..4c6a99f 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -8,12 +8,19 @@ vc4-y := \
vc4_crtc.o \
vc4_drv.o \
vc4_kms.o \
+   vc4_gem.o \
vc4_hdmi.o \
vc4_hvs.o \
+   vc4_irq.o \
vc4_plane.o \
+   vc4_render_cl.o \
+   vc4_trace_points.o \
vc4_v3d.o \
+   vc4_validate.o \
vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
 
 obj-$(CONFIG_DRM_VC4)  += vc4.o
+
+CFLAGS_vc4_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index db58d74..2cfee59 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -74,6 +74,9 @@ static const struct file_operations vc4_drm_fops = {
 };
 
 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+   DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
@@ -83,10 +86,16 @@ static struct drm_driver vc4_drm_driver = {
.driver_features = (DRIVER_MODESET |
DRIVER_ATOMIC |
DRIVER_GEM |
+   DRIVER_HAVE_IRQ |
DRIVER_PRIME),
.lastclose = vc4_lastclose,
.preclose = vc4_drm_preclose,
 
+   .irq_handler = vc4_irq,
+   .irq_preinstall = vc4_irq_preinstall,
+   .irq_postinstall = vc4_irq_postinstall,
+   .irq_uninstall = vc4_irq_uninstall,
+
.enable_vblank = vc4_enable_vblank,
.disable_vblank = vc4_disable_vblank,
.get_vblank_counter = drm_vblank_count,
@@ -181,9 +190,11 @@ static int vc4_drm_bind(struct device *dev)
if (ret)
goto unref;
 
+   vc4_gem_init(drm);
+
ret = component_bind_all(dev, drm);
if (ret)
-   goto unref;
+   goto gem_destroy;
 
ret = drm_dev_register(drm, 0);
if (ret < 0)
@@ -207,6 +218,8 @@ unregister:
drm_dev_unregister(drm);
 unbind_all:
component_unbind_all(dev, drm);
+gem_destroy:
+   vc4_gem_destroy(drm);
 unref:
drm_dev_unref(drm);
vc4_bo_cache_destroy(drm);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 8945463..a3dbfee 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -49,6 +49,48 @@ struct vc4_dev {
 
/* Protects bo_cache and the BO stats. */
struct mutex bo_lock;
+
+   /* Sequence number for the last job queued in job_list.
+* Starts at 0 (no jobs emitted).
+*/
+   uint64_t emit_seqno;
+
+   /* Sequence number for the last completed job on the GPU.
+* Starts at 0 (no jobs completed).
+*/
+   uint64_t finished_seqno;
+
+   /* List of all struct vc4_exec_info for jobs to be executed.
+* The first job in the list is the one currently programmed
+* into ct0ca/ct1ca for execution.
+*/
+   struct list_head job_list;
+   /* List of the finished vc4_exec_infos waiting to be freed by
+* job_done_work.
+*/
+   struct list_head job_done_list;
+   /* Spinlock used to synchronize the job_list and seqno
+* accesses between the 

[PATCH 5/9] drm/vc4: Fix a typo in a V3D debug register.

2015-12-01 Thread Eric Anholt
Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 9e4e904..4e52a0a 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -154,7 +154,7 @@
 #define V3D_PCTRS14  0x006f4
 #define V3D_PCTR15   0x006f8
 #define V3D_PCTRS15  0x006fc
-#define V3D_BGE  0x00f00
+#define V3D_DBGE 0x00f00
 #define V3D_FDBGO0x00f04
 #define V3D_FDBGB0x00f08
 #define V3D_FDBGR0x00f0c
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/9] drm/vc4: Add create and map BO ioctls.

2015-12-01 Thread Eric Anholt
While there exist dumb APIs for creating and mapping BOs, one of the
rules is that drivers doing 3D acceleration have to provide their own
APIs for buffer allocation (besides, the pitch/height parameters of
the dumb alloc don't really make sense for a lot of 3D allocations).

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_bo.c  | 41 ++
 drivers/gpu/drm/vc4/vc4_drv.c |  3 ++
 drivers/gpu/drm/vc4/vc4_drv.h |  4 +++
 include/uapi/drm/Kbuild   |  1 +
 include/uapi/drm/vc4_drm.h| 68 +++
 5 files changed, 117 insertions(+)
 create mode 100644 include/uapi/drm/vc4_drm.h

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 18faa5b..06cba26 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -19,6 +19,7 @@
  */
 
 #include "vc4_drv.h"
+#include "uapi/drm/vc4_drm.h"
 
 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 {
@@ -346,6 +347,46 @@ static void vc4_bo_cache_time_timer(unsigned long data)
schedule_work(&vc4->bo_cache.time_work);
 }
 
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_priv)
+{
+   struct drm_vc4_create_bo *args = data;
+   struct vc4_bo *bo = NULL;
+   int ret;
+
+   /*
+* We can't allocate from the BO cache, because the BOs don't
+* get zeroed, and that might leak data between users.
+*/
+   bo = vc4_bo_create(dev, args->size, false);
+   if (!bo)
+   return -ENOMEM;
+
+   ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
+   drm_gem_object_unreference_unlocked(&bo->base.base);
+
+   return ret;
+}
+
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+   struct drm_vc4_mmap_bo *args = data;
+   struct drm_gem_object *gem_obj;
+
+   gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+   if (!gem_obj) {
+   DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+   return -EINVAL;
+   }
+
+   /* The mmap offset was set up at BO allocation time. */
+   args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
+
+   drm_gem_object_unreference_unlocked(gem_obj);
+   return 0;
+}
+
 void vc4_bo_cache_init(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index da041fa..5fa4688 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -16,6 +16,7 @@
 #include 
 #include "drm_fb_cma_helper.h"
 
+#include "uapi/drm/vc4_drm.h"
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -73,6 +74,8 @@ static const struct file_operations vc4_drm_fops = {
 };
 
 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+   DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
 };
 
 static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 39a1ff5..fddb0a0 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -155,6 +155,10 @@ int vc4_dumb_create(struct drm_file *file_priv,
struct drm_mode_create_dumb *args);
 struct dma_buf *vc4_prime_export(struct drm_device *dev,
 struct drm_gem_object *obj, int flags);
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_priv);
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
 void vc4_bo_cache_init(struct drm_device *dev);
 void vc4_bo_cache_destroy(struct drm_device *dev);
 int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
index 38d4370..974fcd5 100644
--- a/include/uapi/drm/Kbuild
+++ b/include/uapi/drm/Kbuild
@@ -17,4 +17,5 @@ header-y += tegra_drm.h
 header-y += via_drm.h
 header-y += vmwgfx_drm.h
 header-y += msm_drm.h
+header-y += vc4_drm.h
 header-y += virtgpu_drm.h
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
new file mode 100644
index 000..068aab9
--- /dev/null
+++ b/include/uapi/drm/vc4_drm.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2014-2015 Broadcom
+ *
+ * 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 

[PATCH 2/9] drm/vc4: Add a BO cache.

2015-12-01 Thread Eric Anholt
We need to allocate new BOs in the kernel as part of each frame, but
the CMA allocator is way too slow for that.  As an optimization, keep
track of recently-freed BOs and reuse them, with a 1 second timeout to
fully free them back to the system.

This improves 3D performance by about 15%.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_bo.c  | 336 +-
 drivers/gpu/drm/vc4/vc4_debugfs.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c |   6 +-
 drivers/gpu/drm/vc4/vc4_drv.h |  49 +-
 4 files changed, 384 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index ab9f510..18faa5b 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -12,19 +12,229 @@
  * access to system memory with no MMU in between.  To support it, we
  * use the GEM CMA helper functions to allocate contiguous ranges of
  * physical memory for our BOs.
+ *
+ * Since the CMA allocator is very slow, we keep a cache of recently
+ * freed BOs around so that the kernel's allocation of objects for 3D
+ * rendering can return quickly.
  */
 
 #include "vc4_drv.h"
 
-struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
+static void vc4_bo_stats_dump(struct vc4_dev *vc4)
+{
+   DRM_INFO("num bos allocated: %d\n",
+vc4->bo_stats.num_allocated);
+   DRM_INFO("size bos allocated: %dkb\n",
+vc4->bo_stats.size_allocated / 1024);
+   DRM_INFO("num bos used: %d\n",
+vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached);
+   DRM_INFO("size bos used: %dkb\n",
+(vc4->bo_stats.size_allocated -
+ vc4->bo_stats.size_cached) / 1024);
+   DRM_INFO("num bos cached: %d\n",
+vc4->bo_stats.num_cached);
+   DRM_INFO("size bos cached: %dkb\n",
+vc4->bo_stats.size_cached / 1024);
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
+{
+   struct drm_info_node *node = (struct drm_info_node *)m->private;
+   struct drm_device *dev = node->minor->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_bo_stats stats;
+
+   /* Take a snapshot of the current stats with the lock held. */
+   mutex_lock(&vc4->bo_lock);
+   stats = vc4->bo_stats;
+   mutex_unlock(&vc4->bo_lock);
+
+   seq_printf(m, "num bos allocated: %d\n",
+  stats.num_allocated);
+   seq_printf(m, "size bos allocated: %dkb\n",
+  stats.size_allocated / 1024);
+   seq_printf(m, "num bos used: %d\n",
+  stats.num_allocated - stats.num_cached);
+   seq_printf(m, "size bos used: %dkb\n",
+  (stats.size_allocated - stats.size_cached) / 1024);
+   seq_printf(m, "num bos cached: %d\n",
+  stats.num_cached);
+   seq_printf(m, "size bos cached: %dkb\n",
+  stats.size_cached / 1024);
+
+   return 0;
+}
+#endif
+
+static uint32_t bo_page_index(size_t size)
+{
+   return (size / PAGE_SIZE) - 1;
+}
+
+/* Must be called with bo_lock held. */
+static void vc4_bo_destroy(struct vc4_bo *bo)
 {
+   struct drm_gem_object *obj = &bo->base.base;
+   struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+
+   vc4->bo_stats.num_allocated--;
+   vc4->bo_stats.size_allocated -= obj->size;
+   drm_gem_cma_free_object(obj);
+}
+
+/* Must be called with bo_lock held. */
+static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
+{
+   struct drm_gem_object *obj = &bo->base.base;
+   struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+
+   vc4->bo_stats.num_cached--;
+   vc4->bo_stats.size_cached -= obj->size;
+
+   list_del(&bo->unref_head);
+   list_del(&bo->size_head);
+}
+
+static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev,
+size_t size)
+{
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   uint32_t page_index = bo_page_index(size);
+
+   if (vc4->bo_cache.size_list_size <= page_index) {
+   uint32_t new_size = max(vc4->bo_cache.size_list_size * 2,
+   page_index + 1);
+   struct list_head *new_list;
+   uint32_t i;
+
+   new_list = kmalloc_array(new_size, sizeof(struct list_head),
+GFP_KERNEL);
+   if (!new_list)
+   return NULL;
+
+   /* Rebase the old cached BO lists to their new list
+* head locations.
+*/
+   for (i = 0; i < vc4->bo_cache.size_list_size; i++) {
+   

[PATCH 4/9] drm/vc4: Add an API for creating GPU shaders in GEM BOs.

2015-12-01 Thread Eric Anholt
Since we have no MMU, the kernel needs to validate that the submitted
shader code won't make any accesses to memory that the user doesn't
control, which involves banning some operations (general purpose DMA
writes), and tracking where we need to write out pointers for other
operations (texture sampling).  Once it's validated, we return a GEM
BO containing the shader, which doesn't allow mapping for write or
exporting to other subsystems.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/Makefile   |   3 +-
 drivers/gpu/drm/vc4/vc4_bo.c   | 140 
 drivers/gpu/drm/vc4/vc4_drv.c  |   9 +-
 drivers/gpu/drm/vc4/vc4_drv.h  |  50 +++
 drivers/gpu/drm/vc4/vc4_qpu_defines.h  | 264 +++
 drivers/gpu/drm/vc4/vc4_validate_shaders.c | 513 +
 include/uapi/drm/vc4_drm.h |  25 ++
 7 files changed, 999 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_qpu_defines.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate_shaders.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 32b4f9c..eb776a6 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -10,7 +10,8 @@ vc4-y := \
vc4_kms.o \
vc4_hdmi.o \
vc4_hvs.o \
-   vc4_plane.o
+   vc4_plane.o \
+   vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
 
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 06cba26..18dfe3e 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -79,6 +79,12 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
struct drm_gem_object *obj = &bo->base.base;
struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
 
+   if (bo->validated_shader) {
+   kfree(bo->validated_shader->texture_samples);
+   kfree(bo->validated_shader);
+   bo->validated_shader = NULL;
+   }
+
vc4->bo_stats.num_allocated--;
vc4->bo_stats.size_allocated -= obj->size;
drm_gem_cma_free_object(obj);
@@ -315,6 +321,12 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
goto out;
}
 
+   if (bo->validated_shader) {
+   kfree(bo->validated_shader->texture_samples);
+   kfree(bo->validated_shader);
+   bo->validated_shader = NULL;
+   }
+
bo->free_time = jiffies;
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
@@ -347,6 +359,78 @@ static void vc4_bo_cache_time_timer(unsigned long data)
schedule_work(&vc4->bo_cache.time_work);
 }
 
+struct dma_buf *
+vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader) {
+   DRM_ERROR("Attempting to export shader BO\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   return drm_gem_prime_export(dev, obj, flags);
+}
+
+int vc4_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+   struct drm_gem_object *gem_obj;
+   struct vc4_bo *bo;
+   int ret;
+
+   ret = drm_gem_mmap(filp, vma);
+   if (ret)
+   return ret;
+
+   gem_obj = vma->vm_private_data;
+   bo = to_vc4_bo(gem_obj);
+
+   if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
+   DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+   return -EINVAL;
+   }
+
+   /*
+* Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the
+* vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map
+* the whole buffer.
+*/
+   vma->vm_flags &= ~VM_PFNMAP;
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma,
+   bo->base.vaddr, bo->base.paddr,
+   vma->vm_end - vma->vm_start);
+   if (ret)
+   drm_gem_vm_close(vma);
+
+   return ret;
+}
+
+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
+   DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+   return -EINVAL;
+   }
+
+   return drm_gem_cma_prime_mmap(obj, vma);
+}
+
+void *vc4_prime_vmap(struct drm_gem_object *obj)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader) {
+   DRM_ERROR("mmaping of shader BOs not allowed.\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   return drm_gem_cma_pr

[PATCH 9/9] drm/vc4: Add an interface for capturing the GPU state after a hang.

2015-12-01 Thread Eric Anholt
This can be parsed with vc4-gpu-tools tools for trying to figure out
what was going on.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_drv.c |   2 +
 drivers/gpu/drm/vc4/vc4_drv.h |   4 +
 drivers/gpu/drm/vc4/vc4_gem.c | 185 ++
 include/uapi/drm/vc4_drm.h|  45 ++
 4 files changed, 236 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 2cfee59..97226b6 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -80,6 +80,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
+ DRM_ROOT_ONLY),
 };
 
 static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 9a8ee23..cd3e243 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -19,6 +19,8 @@ struct vc4_dev {
 
struct drm_fbdev_cma *fbdev;
 
+   struct vc4_hang_state *hang_state;
+
/* The kernel-space BO cache.  Tracks buffers that have been
 * unreferenced by all other users (refcounts of 0!) but not
 * yet freed, so we can do cheap allocations.
@@ -369,6 +371,8 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_priv);
 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv);
+int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv);
 int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
 int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 void *vc4_prime_vmap(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index a62ca68..fb0b92d 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -40,6 +40,186 @@ vc4_queue_hangcheck(struct drm_device *dev)
  round_jiffies_up(jiffies + msecs_to_jiffies(100)));
 }
 
+struct vc4_hang_state {
+   struct drm_vc4_get_hang_state user_state;
+
+   u32 bo_count;
+   struct drm_gem_object **bo;
+};
+
+static void
+vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state)
+{
+   unsigned int i;
+
+   mutex_lock(&dev->struct_mutex);
+   for (i = 0; i < state->user_state.bo_count; i++)
+   drm_gem_object_unreference(state->bo[i]);
+   mutex_unlock(&dev->struct_mutex);
+
+   kfree(state);
+}
+
+int
+vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv)
+{
+   struct drm_vc4_get_hang_state *get_state = data;
+   struct drm_vc4_get_hang_state_bo *bo_state;
+   struct vc4_hang_state *kernel_state;
+   struct drm_vc4_get_hang_state *state;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   unsigned long irqflags;
+   u32 i;
+   int ret;
+
+   spin_lock_irqsave(&vc4->job_lock, irqflags);
+   kernel_state = vc4->hang_state;
+   if (!kernel_state) {
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+   return -ENOENT;
+   }
+   state = &kernel_state->user_state;
+
+   /* If the user's array isn't big enough, just return the
+* required array size.
+*/
+   if (get_state->bo_count < state->bo_count) {
+   get_state->bo_count = state->bo_count;
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+   return 0;
+   }
+
+   vc4->hang_state = NULL;
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
+   /* Save the user's BO pointer, so we don't stomp it with the memcpy. */
+   state->bo = get_state->bo;
+   memcpy(get_state, state, sizeof(*state));
+
+   bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL);
+   if (!bo_state) {
+   ret = -ENOMEM;
+   goto err_free;
+   }
+
+   for (i = 0; i < state->bo_count; i++) {
+   struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]);
+   u32 handle;
+
+   ret = drm_gem_handle_create(file_priv, kernel_state->bo[i],
+   &handle);
+
+   if (ret) {
+   state->bo_count = i - 1;
+   goto err;
+   }
+   bo_state[i].handle = handle;
+   bo_state[i].paddr = vc4_bo->base.paddr;
+  

[PATCH 6/9] drm/vc4: Bind and initialize the V3D engine.

2015-12-01 Thread Eric Anholt
This is the component of the GPU that does 3D rendering.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/Makefile  |   1 +
 drivers/gpu/drm/vc4/vc4_debugfs.c |   2 +
 drivers/gpu/drm/vc4/vc4_drv.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.h |  13 +++
 drivers/gpu/drm/vc4/vc4_v3d.c | 225 ++
 5 files changed, 242 insertions(+)
 create mode 100644 drivers/gpu/drm/vc4/vc4_v3d.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index eb776a6..e87a6f2 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -11,6 +11,7 @@ vc4-y := \
vc4_hdmi.o \
vc4_hvs.o \
vc4_plane.o \
+   vc4_v3d.o \
vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c 
b/drivers/gpu/drm/vc4/vc4_debugfs.c
index 6bcf96e..d76ad10 100644
--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -22,6 +22,8 @@ static const struct drm_info_list vc4_debugfs_list[] = {
{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
+   {"v3d_ident", vc4_v3d_debugfs_ident, 0},
+   {"v3d_regs", vc4_v3d_debugfs_regs, 0},
 };
 
 #define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index da4be9c..db58d74 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -236,6 +236,7 @@ static struct platform_driver *const component_drivers[] = {
&vc4_hdmi_driver,
&vc4_crtc_driver,
&vc4_hvs_driver,
+   &vc4_v3d_driver,
 };
 
 static int vc4_platform_drm_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index bd77d55..8945463 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -15,6 +15,7 @@ struct vc4_dev {
struct vc4_hdmi *hdmi;
struct vc4_hvs *hvs;
struct vc4_crtc *crtc[3];
+   struct vc4_v3d *v3d;
 
struct drm_fbdev_cma *fbdev;
 
@@ -82,6 +83,11 @@ to_vc4_bo(struct drm_gem_object *bo)
return (struct vc4_bo *)bo;
 }
 
+struct vc4_v3d {
+   struct platform_device *pdev;
+   void __iomem *regs;
+};
+
 struct vc4_hvs {
struct platform_device *pdev;
void __iomem *regs;
@@ -119,6 +125,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
return container_of(encoder, struct vc4_encoder, base);
 }
 
+#define V3D_READ(offset) readl(vc4->v3d->regs + offset)
+#define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset)
 #define HVS_READ(offset) readl(vc4->hvs->regs + offset)
 #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
 
@@ -241,6 +249,11 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
 u32 vc4_plane_dlist_size(struct drm_plane_state *state);
 
+/* vc4_v3d.c */
+extern struct platform_driver vc4_v3d_driver;
+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
+
 /* vc4_validate_shader.c */
 struct vc4_validated_shader_info *
 vc4_validate_shader(struct drm_gem_cma_object *shader_obj);
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
new file mode 100644
index 000..040ad0d
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#ifdef CONFIG_DEBUG_FS
+#define REGDEF(reg) { reg, #reg }
+static const struct {
+   uint32_t reg;
+   const char *name;
+} vc4_reg_defs[] = {
+   REGDEF(V3D_IDENT0),
+   REGDEF(V3D_IDENT1),
+   REGDEF(V3D_IDENT2),
+   REGDEF(V3D_SCRATCH),
+   REGDEF(V3D_L2CACTL),
+   REGDEF(V3D_SLCACTL),
+   REGDEF(V3D_INTCTL),
+   REGDEF(V3D_INTENA),
+   REGDEF(V3D_INTDIS),
+   REGDEF(V3D_CT0CS),
+ 

Re: [PATCH 4/9] drm/vc4: Add an API for creating GPU shaders in GEM BOs.

2015-12-02 Thread Eric Anholt
Emil Velikov  writes:

> Hi Eric,
>
> On 1 December 2015 at 20:35, Eric Anholt  wrote:
>> Since we have no MMU, the kernel needs to validate that the submitted
>> shader code won't make any accesses to memory that the user doesn't
>> control, which involves banning some operations (general purpose DMA
>> writes), and tracking where we need to write out pointers for other
>> operations (texture sampling).  Once it's validated, we return a GEM
>> BO containing the shader, which doesn't allow mapping for write or
>> exporting to other subsystems.
>>
>> Signed-off-by: Eric Anholt 
>> ---
>>  drivers/gpu/drm/vc4/Makefile   |   3 +-
>>  drivers/gpu/drm/vc4/vc4_bo.c   | 140 
>>  drivers/gpu/drm/vc4/vc4_drv.c  |   9 +-
>>  drivers/gpu/drm/vc4/vc4_drv.h  |  50 +++
>>  drivers/gpu/drm/vc4/vc4_qpu_defines.h  | 264 +++
>
> May I suggest that one 'exports' the header to something like
> libdrm_vc4 ? There are patches in flight for nouveau which in similar
> fashion, allow userspare to reuse existing api/abi.

I'll be putting this header in libdrm for use by Mesa and vc4-gpu-tools.
It will still have to live in the kernel as well, though.


signature.asc
Description: PGP signature


Re: [PATCH 7/9] drm/vc4: Add support for drawing 3D frames.

2015-12-02 Thread Eric Anholt
Emil Velikov  writes:

> Hi Eric,
>
> On 1 December 2015 at 20:35, Eric Anholt  wrote:
>> The user submission is basically a pointer to a command list and a
>> pointer to uniforms.  We copy those in to the kernel, validate and
>> relocate them, and store the result in a GPU BO which we queue for
>> execution.
>>
>> Signed-off-by: Eric Anholt 
>> ---
>>  drivers/gpu/drm/vc4/Makefile   |   7 +
>>  drivers/gpu/drm/vc4/vc4_drv.c  |  15 +-
>>  drivers/gpu/drm/vc4/vc4_drv.h  | 192 +++
>>  drivers/gpu/drm/vc4/vc4_gem.c  | 640 ++
>>  drivers/gpu/drm/vc4/vc4_irq.c  | 210 
>>  drivers/gpu/drm/vc4/vc4_packet.h   | 399 ++
>>  drivers/gpu/drm/vc4/vc4_render_cl.c| 631 ++
>>  drivers/gpu/drm/vc4/vc4_trace.h|  63 +++
>>  drivers/gpu/drm/vc4/vc4_trace_points.c |  14 +
>>  drivers/gpu/drm/vc4/vc4_v3d.c  |  37 ++
>>  drivers/gpu/drm/vc4/vc4_validate.c | 955 
>> +
>>  include/uapi/drm/vc4_drm.h | 141 +
>>  12 files changed, 3303 insertions(+), 1 deletion(-)
>
> Am I assuming correct that the above are the exact same ones copied in
> mesa (and used only then simulator is used) ? In the short term
> keeping the two in sync would be fine, although wondering if you have
> plans to reshuffle things in the long term ?

This code is not exactly synced with Mesa, but I do sync between them on
a regular basis.  The in-Mesa copy is secondary, and just a way for me
to get testing done faster (in the simulation environment with gdb) than
I can in the kernel with printfs.


signature.asc
Description: PGP signature


Re: [PATCH 9/9] drm/vc4: Add an interface for capturing the GPU state after a hang.

2015-12-02 Thread Eric Anholt
Emil Velikov  writes:

> On 1 December 2015 at 20:35, Eric Anholt  wrote:
>> This can be parsed with vc4-gpu-tools tools for trying to figure out
>> what was going on.
>>
> I might be pushing my luck here ... have you thought about basing
> (forking) vc4-gpu-tools of intel-gpu-tools ? I'd imagine that the
> macros and helpers will come in handy, despite that some are quite
> intel specific.
>
> On a related note - with the above project in place I'd imagine you
> have (re)considered about having libdrm-vc4 ? Copying hunks around
> might lead to interesting moments (as you have already noticed :-P)
>
> On that note I'll stop now with beating the libdrm drum :-)

The headers and code that I copy between the two userspace locations
will go in libdrm when I have a kernel ABI, but vc4_drm.h can't go in
until merging to the kernel, and there's not a whole lot of point
without that.

Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
I've actually tried to build and use the kms testing stuff on vc4, and
it was a total bust.  Someone needs to do a lot of work to make igt
useful for non-intel.  If you'd like me to build my vc4 testing inside
of igt, I'd someone to demo one of my tests building inside of igt, with
the test runner working and none of the intel-specific tests reporting
failure, and get me permission to just push code to that repository
(It's hard enough getting piglit tests reviewed, vc4-specific tests and
tools would never get review).


signature.asc
Description: PGP signature


Re: [PATCH v2 1/3] clk: bcm2835: Always round up clock divisor

2015-12-03 Thread Eric Anholt
Remi Pommarel  writes:

> Hi,
>
> On Wed, Nov 18, 2015 at 10:25:45AM -0800, Eric Anholt wrote:
>> Remi Pommarel  writes:
>> 
>> > Make bcm2835_clock_choose_div always round up the chosen MASH divisor so 
>> > that
>> > the resulting average rate will not be higher than the requested one.
>> >
>> > Signed-off-by: Remi Pommarel 
>> > ---
>> >  drivers/clk/bcm/clk-bcm2835.c | 15 ---
>> >  1 file changed, 8 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
>> > index 39bf582..1237716 100644
>> > --- a/drivers/clk/bcm/clk-bcm2835.c
>> > +++ b/drivers/clk/bcm/clk-bcm2835.c
>> > @@ -1152,18 +1152,19 @@ static u32 bcm2835_clock_choose_div(struct clk_hw 
>> > *hw,
>> >  {
>> >struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
>> >const struct bcm2835_clock_data *data = clock->data;
>> > -  u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0);
>> > +  u32 unused_frac_mask =
>> > +  GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
>> >u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
>> > +  u64 rem;
>> >u32 div;
>> >  
>> > -  do_div(temp, rate);
>> > +  rem = do_div(temp, rate);
>> >div = temp;
>> >  
>> > -  /* Round and mask off the unused bits */
>> > -  if (unused_frac_mask != 0) {
>> > -  div += unused_frac_mask >> 1;
>> > -  div &= ~unused_frac_mask;
>> > -  }
>> > +  /* Round up and mask off the unused bits */
>> > +  if ((div & unused_frac_mask) != 0 || rem != 0)
>> > +  div += unused_frac_mask + 1;
>> > +  div &= ~unused_frac_mask;
>> 
>> Suppose we've got 8 of our 12 frac bits populated.  You've added a ">>
>> 1" to the unused_frac_mask, so it's only 0x7 instead of 0xf.  When you
>> say "round up", you add 0x8 (the high bit of the unused mask") then and
>> with ~0x7.  If you started with 0x1 in the low bits of div, you'd end up
>> with 0x8, so you've set an unused bit instead of actually rounding up.
>> 
>> Did my logic work, here?  I think you just want to drop the ">>1" in
>> unused_frac_mask.
>
> I don't think so.
>
> If we have 8 of our 12 frac bits populated GENMASK(12 - 8, 0) will be 0x1f
> because GENMASK(4, 0) generates a mask from bit at position 0 to bit at
> position 4 inclusively (which is the fifth bit). So GENMASK(4, 0) >> 1 will
> be 0xf which is what we want here.

Oh, that was an existing bug you were fixing!  You're right.  I even got
the GENMASK call right at the end of the function, I'd just botched this
one.

Reviewed-by: Eric Anholt 


signature.asc
Description: PGP signature


Re: [PATCH v2 2/3] clk: bcm2835: Support for clock parent selection

2015-12-03 Thread Eric Anholt
Remi Pommarel  writes:

> On Wed, Nov 18, 2015 at 10:30:17AM -0800, Eric Anholt wrote:
>
> [...]
>
>> > +static int bcm2835_clock_determine_rate(struct clk_hw *hw,
>> > +  struct clk_rate_request *req)
>> > +{
>> > +  struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
>> > +  struct clk_hw *parent, *best_parent = NULL;
>> > +  struct clk_rate_request parent_req;
>> > +  unsigned long rate, best_rate = 0;
>> > +  unsigned long prate, best_prate = 0;
>> > +  size_t i;
>> > +  u32 div;
>> > +
>> > +  /*
>> > +   * Select parent clock that results in the closest but lower rate
>> > +   */
>> > +  for (i = 0; i < clk_hw_get_num_parents(hw); ++i) {
>> > +  parent = clk_hw_get_parent_by_index(hw, i);
>> > +  if (!parent)
>> > +  continue;
>> > +  parent_req = *req;
>> 
>> parent_req appears dead, so it should be removed.
>
> Yes, will do thanks.
>
>> > +  prate = clk_hw_get_rate(parent);
>> > +  div = bcm2835_clock_choose_div(hw, req->rate, prate);
>> > +  rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
>> > +  if (rate > best_rate && rate <= req->rate) {
>> > +  best_parent = parent;
>> > +  best_prate = prate;
>> > +  best_rate = rate;
>> > +  }
>> > +  }
>> > +
>> > +  if (!best_parent)
>> > +  return -EINVAL;
>> > +
>> > +  req->best_parent_hw = best_parent;
>> > +  req->best_parent_rate = best_prate;
>> 
>> I think you're supposed to req->rate = best_rate, here, too.  With these
>> two fixes,
>
> I did not set req->rate to best_rate in order to avoid rounding down
> twice the actual clock rate.
>
> Indeed with patch 1 from this patchset bcm2835_clock_choose_div()
> chooses a divisor that produces a rate lower or equal to the requested
> one. As we call bcm2835_clock_choose_div() twice when using
> clk_set_rate() (once with ->determine_rate() and once with ->set_rate()),
> if I set req->rate in bcm2835_clock_determine_rate to the rounded down
> one, the final rate will likely be again rounded down in
> bcm2835_clock_set_rate().

If we pass bcm2835_clock_rate_from_divisor(bcm2835_clock_choose_div()),
to bcm2835_clock_choose_div(), will it actually give a different divisor
than the first call?  (That seems like an unfortunate problem in our
implementation, if so).

I'd be willing to go along with this, but if so I'd like a comment
explaining why we aren't setting the field that we should pretty
obviously be setting.


signature.asc
Description: PGP signature


Re: [PATCH 8/9] drm/vc4: Add support for async pageflips.

2015-12-03 Thread Eric Anholt
Daniel Stone  writes:

> Hi,
>
> On 1 December 2015 at 20:35, Eric Anholt  wrote:
>> An async pageflip stores the modeset to be done and executes it once
>> the BOs are ready to be displayed.  This gets us about 3x performance
>> in full screen rendering with pageflipping.
>
> Looks good, but you're missing a preclose callback to reap dead events, a la:
> https://git.collabora.com/cgit/user/daniels/linux.git/commit/?h=wip/4.4.x/rockchip-drm-fixes&id=d14f21bcd7e7a1b9ca129c411a9da9c911037965
>
> (and parent commit to wire that through to core DRM preclose)

We've already got a preclose callback that reaps crtc->event -- see
vc4_cancel_page_flip().


signature.asc
Description: PGP signature


[PATCH] drm: Use the driver's gem_object_free function from CMA helpers.

2015-12-14 Thread Eric Anholt
VC4 wraps the CMA objects in its own structures, so it needs to do its
own teardown (waiting for GPU to finish, updating bo_stats tracking).
The other CMA drivers are using drm_gem_cma_free_object as their
gem_free_object, so this should be a no-op for them.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/drm_fb_cma_helper.c  | 6 +++---
 drivers/gpu/drm/drm_gem_cma_helper.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index 5c1aca4..99b5673 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -279,7 +279,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper 
*helper,
if (!fbi) {
dev_err(dev->dev, "Failed to allocate framebuffer info.\n");
ret = -ENOMEM;
-   goto err_drm_gem_cma_free_object;
+   goto err_gem_free_object;
}
 
fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1);
@@ -322,8 +322,8 @@ err_drm_fb_cma_destroy:
drm_fb_cma_destroy(fb);
 err_framebuffer_release:
framebuffer_release(fbi);
-err_drm_gem_cma_free_object:
-   drm_gem_cma_free_object(&obj->base);
+err_gem_free_object:
+   dev->driver->gem_free_object(&obj->base);
return ret;
 }
 
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 7dcb43f..b409123 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
drm_device *drm,
return cma_obj;
 
 error:
-   drm_gem_cma_free_object(&cma_obj->base);
+   drm->driver->gem_free_object(&cma_obj->base);
return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
@@ -171,7 +171,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
return cma_obj;
 
 err_handle_create:
-   drm_gem_cma_free_object(gem_obj);
+   drm->driver->gem_free_object(gem_obj);
 
return ERR_PTR(ret);
 }
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drm: Use the driver's gem_object_free function from CMA helpers.

2015-12-15 Thread Eric Anholt
Daniel Vetter  writes:

> On Mon, Dec 14, 2015 at 04:26:26PM -0800, Eric Anholt wrote:
>> VC4 wraps the CMA objects in its own structures, so it needs to do its
>> own teardown (waiting for GPU to finish, updating bo_stats tracking).
>> The other CMA drivers are using drm_gem_cma_free_object as their
>> gem_free_object, so this should be a no-op for them.
>> 
>> Signed-off-by: Eric Anholt 
>
> Reviewed-by: Daniel Vetter 
>
> Since vc4 landed already I'll pull this into drm-misc.

Sounds good to me.  Thanks!


signature.asc
Description: PGP signature


[PATCH v3 4/4] ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT.

2015-12-15 Thread Eric Anholt
From: Alexander Aring 

This connects the USB driver to the USB power domain, so that USB can
actually be turned on at boot if the bootloader didn't do it for us.

Signed-off-by: Alexander Aring 
Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 11 +++
 arch/arm/boot/dts/bcm2835.dtsi |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 3572f03..f828202 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,3 +1,4 @@
+#include 
 #include "bcm2835.dtsi"
 
 / {
@@ -20,6 +21,12 @@
compatible = "raspberrypi,bcm2835-firmware";
mboxes = <&mailbox>;
};
+
+   power: power {
+   compatible = "raspberrypi,bcm2835-power";
+   firmware = <&firmware>;
+   #power-domain-cells = <1>;
+   };
};
 };
 
@@ -60,3 +67,7 @@
status = "okay";
bus-width = <4>;
 };
+
+&usb {
+   power-domains = <&power RPI_POWER_DOMAIN_USB>;
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index aef64de..6d62af0 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -177,7 +177,7 @@
status = "disabled";
};
 
-   usb@7e98 {
+   usb: usb@7e98 {
compatible = "brcm,bcm2835-usb";
reg = <0x7e98 0x1>;
interrupts = <1 9>;
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/4] Raspberry Pi power domains

2015-12-15 Thread Eric Anholt
Since the pm_genpd_exit() patch is still going through review, and
other drivers in the tree just ignore the error cases, Ulf offered to
merge the series as a builtin driver not depending on that interface.
We still avoid dangling pointer references, by just continuing with
probing if of_genpd_add_provider_onecell() fails.  We can easily go
back and update the driver when a pm_genpd_exit() lands.

Alexander Aring (3):
  ARM: bcm2835: add rpi power domain driver
  dt-bindings: add rpi power domain driver bindings
  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT.

Eric Anholt (1):
  ARM: bcm2835: Define two new packets from the latest firmware.

 .../bindings/arm/bcm/raspberrypi,bcm2835-power.txt |  47 
 arch/arm/boot/dts/bcm2835-rpi.dtsi |  11 +
 arch/arm/boot/dts/bcm2835.dtsi |   2 +-
 arch/arm/mach-bcm/Kconfig  |  10 +
 arch/arm/mach-bcm/Makefile |   1 +
 arch/arm/mach-bcm/raspberrypi-power.c  | 247 +
 include/dt-bindings/arm/raspberrypi-power.h|  41 
 include/soc/bcm2835/raspberrypi-firmware.h |   2 +
 8 files changed, 360 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt
 create mode 100644 arch/arm/mach-bcm/raspberrypi-power.c
 create mode 100644 include/dt-bindings/arm/raspberrypi-power.h

-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/4] ARM: bcm2835: Define two new packets from the latest firmware.

2015-12-15 Thread Eric Anholt
These packets give us direct access to the firmware's power management
code, as opposed to GET/SET_POWER_STATE packets that only had a couple
of domains implemented.

Signed-off-by: Eric Anholt 
---
 include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/soc/bcm2835/raspberrypi-firmware.h 
b/include/soc/bcm2835/raspberrypi-firmware.h
index c07d74a..3fb3571 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -72,10 +72,12 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012,
RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =   0x00030014,
RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020,
+   RPI_FIRMWARE_GET_DOMAIN_STATE =   0x00030030,
RPI_FIRMWARE_SET_CLOCK_STATE =0x00038001,
RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002,
RPI_FIRMWARE_SET_VOLTAGE =0x00038003,
RPI_FIRMWARE_SET_TURBO =  0x00038009,
+   RPI_FIRMWARE_SET_DOMAIN_STATE =   0x00038030,
 
/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE =   0x00040001,
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/4] ARM: bcm2835: add rpi power domain driver

2015-12-15 Thread Eric Anholt
From: Alexander Aring 

This patch adds support for several power domains on Raspberry Pi,
including USB (so it can be enabled even if the bootloader didn't do
it), and graphics.

This patch is the combined work of Eric Anholt (who wrote USB support
inside of the Raspberry Pi firmware driver, and wrote the non-USB
domain support) and Alexander Aring (who separated the original USB
work out from the firmware driver).

Signed-off-by: Alexander Aring 
Signed-off-by: Eric Anholt 
---

v2: Add support for power domains other than USB, using the new
firmware interface, reword commit message (changes by Eric)

v3: Restructure as a builtin driver, and drop
of_genpd_add_provider_onecell error handling to avoid
pm_genpd_exit() dependency until that API can be settled.  Clean
up copyright header, add missing ISP initialization, and fix typo
in transposer's name.

 arch/arm/mach-bcm/Kconfig   |  10 ++
 arch/arm/mach-bcm/Makefile  |   1 +
 arch/arm/mach-bcm/raspberrypi-power.c   | 247 
 include/dt-bindings/arm/raspberrypi-power.h |  41 +
 4 files changed, 299 insertions(+)
 create mode 100644 arch/arm/mach-bcm/raspberrypi-power.c
 create mode 100644 include/dt-bindings/arm/raspberrypi-power.h

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 8c53c55..0f23bad 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -134,6 +134,16 @@ config ARCH_BCM2835
  This enables support for the Broadcom BCM2835 SoC. This SoC is
  used in the Raspberry Pi and Roku 2 devices.
 
+config RASPBERRYPI_POWER
+   bool "Raspberry Pi power domain driver"
+   depends on ARCH_BCM2835 || COMPILE_TEST
+   depends on RASPBERRYPI_FIRMWARE
+   select PM_GENERIC_DOMAINS if PM
+   select PM_GENERIC_DOMAINS_OF if PM
+   help
+ This enables support for the RPi power domains which can be enabled
+ or disabled via the RPi firmware.
+
 config ARCH_BCM_63XX
bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
depends on MMU
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 892261f..fec2d6b 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -36,6 +36,7 @@ endif
 
 # BCM2835
 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
+obj-$(CONFIG_RASPBERRYPI_POWER)+= raspberrypi-power.o
 
 # BCM5301X
 obj-$(CONFIG_ARCH_BCM_5301X)   += bcm_5301x.o
diff --git a/arch/arm/mach-bcm/raspberrypi-power.c 
b/arch/arm/mach-bcm/raspberrypi-power.c
new file mode 100644
index 000..9dc8b43
--- /dev/null
+++ b/arch/arm/mach-bcm/raspberrypi-power.c
@@ -0,0 +1,247 @@
+/* (C) 2015 Pengutronix, Alexander Aring 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Authors:
+ * Alexander Aring 
+ * Eric Anholt 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Firmware indices for the old power domains interface.  Only a few
+ * of them were actually implemented.
+ */
+#define RPI_OLD_POWER_DOMAIN_USB   3
+#define RPI_OLD_POWER_DOMAIN_V3D   10
+
+struct rpi_power_domain {
+   u32 domain;
+   bool enabled;
+   bool old_interface;
+   struct generic_pm_domain base;
+   struct rpi_firmware *fw;
+};
+
+struct rpi_power_domains {
+   bool has_new_interface;
+   struct genpd_onecell_data xlate;
+   struct rpi_firmware *fw;
+   struct rpi_power_domain domains[RPI_POWER_DOMAIN_COUNT];
+};
+
+/*
+ * Packet definition used by RPI_FIRMWARE_SET_POWER_STATE and
+ * RPI_FIRMWARE_SET_DOMAIN_STATE
+ */
+struct rpi_power_domain_packet {
+   u32 domain;
+   u32 on;
+} __packet;
+
+/*
+ * Asks the firmware to enable or disable power on a specific power
+ * domain.
+ */
+static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on)
+{
+   struct rpi_power_domain_packet packet;
+
+   packet.domain = rpi_domain->domain;
+   packet.on = on;
+   return rpi_firmware_property(rpi_domain->fw,
+rpi_domain->old_interface ?
+RPI_FIRMWARE_SET_POWER_STATE :
+RPI_FIRMWARE_SET_DOMAIN_STATE,
+&packet, sizeof(packet));
+}
+
+static int rpi_domain_off(struct generic_pm_domain *domain)
+{
+   struct rpi_power_domain *rpi_domain =
+   container_of(domain, struct rpi_power_domain, base);
+
+   return rpi_firmware_set_power(rpi_domain, false);
+}
+
+static int rpi_domain_on(struct generic_pm_domain *domain)
+{
+   struct rpi_power_domain *rpi_domain =
+   container_of(domain, struct rpi_power_domain, base);
+
+   return rpi_firmware_set_power(rpi_domain, true);
+}

[PATCH v3 3/4] dt-bindings: add rpi power domain driver bindings

2015-12-15 Thread Eric Anholt
From: Alexander Aring 

This patch adds devicetree tree bindings for the Raspberry Pi power
domain driver.

Signed-off-by: Alexander Aring 
Acked-by: Rob Herring 
Signed-off-by: Eric Anholt 
---

v2: Add the new domains present in v2 to the list.

 .../bindings/arm/bcm/raspberrypi,bcm2835-power.txt | 47 ++
 1 file changed, 47 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt

diff --git 
a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt 
b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt
new file mode 100644
index 000..30942cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-power.txt
@@ -0,0 +1,47 @@
+Raspberry Pi power domain driver
+
+Required properties:
+
+- compatible:  Should be "raspberrypi,bcm2835-power".
+- firmware:Reference to the RPi firmware device node.
+- #power-domain-cells: Should be <1>, we providing multiple power domains.
+
+The valid defines for power domain are:
+
+ RPI_POWER_DOMAIN_I2C0
+ RPI_POWER_DOMAIN_I2C1
+ RPI_POWER_DOMAIN_I2C2
+ RPI_POWER_DOMAIN_VIDEO_SCALER
+ RPI_POWER_DOMAIN_VPU1
+ RPI_POWER_DOMAIN_HDMI
+ RPI_POWER_DOMAIN_USB
+ RPI_POWER_DOMAIN_VEC
+ RPI_POWER_DOMAIN_JPEG
+ RPI_POWER_DOMAIN_H264
+ RPI_POWER_DOMAIN_V3D
+ RPI_POWER_DOMAIN_ISP
+ RPI_POWER_DOMAIN_UNICAM0
+ RPI_POWER_DOMAIN_UNICAM1
+ RPI_POWER_DOMAIN_CCP2RX
+ RPI_POWER_DOMAIN_CSI2
+ RPI_POWER_DOMAIN_CPI
+ RPI_POWER_DOMAIN_DSI0
+ RPI_POWER_DOMAIN_DSI1
+ RPI_POWER_DOMAIN_TRANSPOSER
+ RPI_POWER_DOMAIN_CCP2TX
+ RPI_POWER_DOMAIN_CDP
+ RPI_POWER_DOMAIN_ARM
+
+Example:
+
+power: power {
+   compatible = "raspberrypi,bcm2835-power";
+   firmware = <&firmware>;
+   #power-domain-cells = <1>;
+};
+
+Example for using power domain:
+
+&usb {
+   power-domains = <&power RPI_POWER_DOMAIN_USB>;
+};
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/4] clk: bcm2835: Add support for programming the audio domain clocks.

2015-09-10 Thread Eric Anholt
Eric Anholt  writes:

> This adds support for enabling, disabling, and setting the rate of the
> audio domain clocks.  It will be necessary for setting the pixel clock
> for HDMI in the VC4 driver and let us write a cpufreq driver.  It will
> also improve compatibility with user changes to the firmware's
> config.txt, since our previous fixed clocks are unaware of it.
>
> The firmware also has support for configuring the clocks through the
> mailbox channel, but the pixel clock setup by the firmware doesn't
> work, and it's Raspberry Pi specific anyway.  The only conflicts we
> should have with the firmware would be if we made firmware calls that
> result in clock management (like opening firmware V3D or ISP access,
> which we don't support in upstream), or on hardware over-thermal or
> under-voltage (when the firmware would rewrite PLLB to take the ARM
> out of overclock).  If that happens, our cached .recalc_rate() results
> would be incorrect, but that's no worse than our current state where
> we used fixed clocks.
>
> The existing fixed clocks in the code are left in place to provide
> backwards compatibility with old device tree files.
>
> Signed-off-by: Eric Anholt 
> ---

> + onecell->clk_num = BCM2835_CLOCK_COUNT;
> + onecell->clks = kzalloc(sizeof(*onecell->clks), GFP_KERNEL);

Review of another clock driver I wrote pointed out that I missed the
multiply by BCM2835_CLOCK_COUNT here.  I'll send an updated version.


signature.asc
Description: PGP signature


[PATCH v2 1/4] clk: bcm2835: Move under bcm/ with other Broadcom SoC clk drivers.

2015-09-10 Thread Eric Anholt
clk-bcm2835.c predates the drivers under bcm/, but all the new BCM
drivers are going in there so let's follow them.

Signed-off-by: Eric Anholt 
---
 drivers/clk/Makefile| 1 -
 drivers/clk/bcm/Makefile| 1 +
 drivers/clk/{ => bcm}/clk-bcm2835.c | 0
 3 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/clk/{ => bcm}/clk-bcm2835.c (100%)

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c4cf075..1bdbe9b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -19,7 +19,6 @@ endif
 obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)   += clk-axm5516.o
-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
 obj-$(CONFIG_COMMON_CLK_CDCE706)   += clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)   += clk-efm32gg.o
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index 8a7a477..ee2349b 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_CLK_BCM_KONA)  += clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
 obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o 
clk-iproc-asiu.o
+obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
 obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
similarity index 100%
rename from drivers/clk/clk-bcm2835.c
rename to drivers/clk/bcm/clk-bcm2835.c
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/4] ARM: bcm2835: Switch to using the new clock driver support.

2015-09-10 Thread Eric Anholt
This will give us the ability to set the pixel and HDMI state machine
clocks for the VC4 KMS driver, change the CPU frequency, and
potentially gate clocks in the future (once we also write a power
domain driver).  It also gives the uart an explicit clock reference,
so that we don't need to change the physical addresses of the old
fixed clk_bcm2835.c clocks for Raspberry Pi 2 port.

Two clocks get their frequencies updated as a result of this.  One is
uart's apb_pclk, which was previously accidentally grabbing the fixed
uart0_pclk due to the apb_pclk not having clk_register_clkdev()
called.  The uart doesn't seem to do anything with apb_pclk other than
make sure it's on, so that appears safe (also, as far as I can see,
the apb clock is actually the same as the VPU clock).  The other is
EMMC, which according to the docs was supposed to be in the 50-100Mhz
range, but it turns out the firmware needed to change to running it at
the 250Mhz core clock speed to avoid a bug in clock domain crossing.

Additionally, anything using BCM2835_CLOCK_VPU will now have a correct
clock rate if the user configures the boot-time core clock speed using
config.txt.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835.dtsi | 52 +++---
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..a6a55b7 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,4 +1,5 @@
 #include 
+#include 
 #include "skeleton.dtsi"
 
 / {
@@ -21,6 +22,10 @@
compatible = "brcm,bcm2835-system-timer";
reg = <0x7e003000 0x1000>;
interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+   /* This could be a reference to BCM2835_CLOCK_TIMER,
+* but we don't have the driver using the common clock
+* support yet.
+*/
clock-frequency = <100>;
};
 
@@ -57,6 +62,17 @@
reg = <0x7e10 0x28>;
};
 
+   clocks: cprman@7e101000 {
+   compatible = "brcm,bcm2835-cprman";
+   #clock-cells = <1>;
+   reg = <0x7e101000 0x2000>;
+
+   /* CPRMAN derives everything from the platform's
+* oscillator.
+*/
+   clocks = <&clk_osc>;
+   };
+
rng@7e104000 {
compatible = "brcm,bcm2835-rng";
reg = <0x7e104000 0x10>;
@@ -96,7 +112,9 @@
compatible = "brcm,bcm2835-pl011", "arm,pl011", 
"arm,primecell";
reg = <0x7e201000 0x1000>;
interrupts = <2 25>;
-   clock-frequency = <300>;
+   clocks = <&clocks BCM2835_CLOCK_UART>,
+<&clocks BCM2835_CLOCK_VPU>;
+   clock-names = "uartclk", "apb_pclk";
arm,primecell-periphid = <0x00241011>;
};
 
@@ -115,7 +133,7 @@
compatible = "brcm,bcm2835-spi";
reg = <0x7e204000 0x1000>;
interrupts = <2 22>;
-   clocks = <&clk_spi>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -125,7 +143,7 @@
compatible = "brcm,bcm2835-i2c";
reg = <0x7e205000 0x1000>;
interrupts = <2 21>;
-   clocks = <&clk_i2c>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -135,7 +153,7 @@
compatible = "brcm,bcm2835-sdhci";
reg = <0x7e30 0x100>;
interrupts = <2 30>;
-   clocks = <&clk_mmc>;
+   clocks = <&clocks BCM2835_CLOCK_EMMC>;
status = "disabled";
};
 
@@ -143,7 +161,7 @@
compatible = "brcm,bcm2835-i2c";
reg = <0x7e804000 0x1000>;
  

[PATCH v2 3/4] clk: bcm2835: Add support for programming the audio domain clocks.

2015-09-10 Thread Eric Anholt
This adds support for enabling, disabling, and setting the rate of the
audio domain clocks.  It will be necessary for setting the pixel clock
for HDMI in the VC4 driver and let us write a cpufreq driver.  It will
also improve compatibility with user changes to the firmware's
config.txt, since our previous fixed clocks are unaware of it.

The firmware also has support for configuring the clocks through the
mailbox channel, but the pixel clock setup by the firmware doesn't
work, and it's Raspberry Pi specific anyway.  The only conflicts we
should have with the firmware would be if we made firmware calls that
result in clock management (like opening firmware V3D or ISP access,
which we don't support in upstream), or on hardware over-thermal or
under-voltage (when the firmware would rewrite PLLB to take the ARM
out of overclock).  If that happens, our cached .recalc_rate() results
would be incorrect, but that's no worse than our current state where
we used fixed clocks.

The existing fixed clocks in the code are left in place to provide
backwards compatibility with old device tree files.

Signed-off-by: Eric Anholt 
---

v2: Fix onecell->clks[] allocation size.

 drivers/clk/bcm/clk-bcm2835.c | 1424 -
 1 file changed, 1423 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 6b950ca..fe4be50 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Broadcom
+ * Copyright (C) 2010,2015 Broadcom
  * Copyright (C) 2012 Stephen Warren
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,10 +17,267 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/**
+ * DOC: BCM2835 CPRMAN (clock manager for the "audio" domain)
+ *
+ * The clock tree on the 2835 has several levels.  There's a root
+ * oscillator running at 19.2Mhz.  After the oscillator there are 4
+ * PLLs, roughly divided as "camera", "ARM", "core", "DSI displays",
+ * and "HDMI displays".  Those 5 PLLs each can divide their output to
+ * produce up to 4 channels.  Finally, there is the level of clocks to
+ * be consumed by other hardware components (like "H264" or "HDMI
+ * state machine"), which divide off of some subset of the PLL
+ * channels.
+ *
+ * All of the clocks in the tree are exposed in the DT, because the DT
+ * may want to make assignments of the final layer of clocks to the
+ * PLL channels, and some components of the hardware will actually
+ * skip layers of the tree (for example, the pixel clock comes
+ * directly from the PLLH PIX channel without using a CM_*CTL clock
+ * generator).
+ */
+
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
+#include 
+
+#define CM_PASSWORD0x5a00
+
+#define CM_GNRICCTL0x000
+#define CM_GNRICDIV0x004
+# define CM_DIV_FRAC_BITS  12
+
+#define CM_VPUCTL  0x008
+#define CM_VPUDIV  0x00c
+#define CM_SYSCTL  0x010
+#define CM_SYSDIV  0x014
+#define CM_PERIACTL0x018
+#define CM_PERIADIV0x01c
+#define CM_PERIICTL0x020
+#define CM_PERIIDIV0x024
+#define CM_H264CTL 0x028
+#define CM_H264DIV 0x02c
+#define CM_ISPCTL  0x030
+#define CM_ISPDIV  0x034
+#define CM_V3DCTL  0x038
+#define CM_V3DDIV  0x03c
+#define CM_CAM0CTL 0x040
+#define CM_CAM0DIV 0x044
+#define CM_CAM1CTL 0x048
+#define CM_CAM1DIV 0x04c
+#define CM_CCP2CTL 0x050
+#define CM_CCP2DIV 0x054
+#define CM_DSI0ECTL0x058
+#define CM_DSI0EDIV0x05c
+#define CM_DSI0PCTL0x060
+#define CM_DSI0PDIV0x064
+#define CM_DPICTL  0x068
+#define CM_DPIDIV  0x06c
+#define CM_GP0CTL  0x070
+#define CM_GP0DIV  0x074
+#define CM_GP1CTL  0x078
+#define CM_GP1DIV  0x07c
+#define CM_GP2CTL  0x080
+#define CM_GP2DIV  0x084
+#define CM_HSMCTL  0x088
+#define CM_HSMDIV  0x08c
+#define CM_OTPCTL  0x090
+#define CM_OTPDIV  0x094
+#define CM_PWMCTL  0x0a0
+#define CM_PWMDIV  0x0a4
+#define CM_SMICTL  0x0b0
+#define CM_SMIDIV  0x0b4
+#define CM_TSENSCTL0x0e0
+#define CM_TSENSDIV0x0e4
+#define CM_TIMERCTL0x0e8
+#define CM_TIMERDIV0x0ec
+#define CM_UARTCTL 0x0f0
+#define CM_UARTDIV 0x0f4
+#define CM_VECCTL  0x0f8
+#define CM_VECDIV  0x0fc
+#define CM_PULSECTL0x190
+#define CM_PULSEDIV0x194

[PATCH v2 2/4] clk: bcm2835: Add binding docs for the new platform clock driver.

2015-09-10 Thread Eric Anholt
Previously we've only supported a few fixed clocks based on
assumptions about how the firmware sets up the clocks, but this
binding will let us control the actual (audio power domain) clock
manager.

Signed-off-by: Eric Anholt 
---
 .../bindings/clock/brcm,bcm2835-cprman.txt | 45 +
 include/dt-bindings/clock/bcm2835.h| 47 ++
 2 files changed, 92 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
 create mode 100644 include/dt-bindings/clock/bcm2835.h

diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt 
b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
new file mode 100644
index 000..e56a1df
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
@@ -0,0 +1,45 @@
+Broadcom BCM2835 CPRMAN clocks
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The CPRMAN clock controller generates clocks in the audio power domain
+of the BCM2835.  There is a level of PLLs deriving from an external
+oscillator, a level of PLL dividers that produce channels off of the
+few PLLs, and a level of mostly-generic clock generators sourcing from
+the PLL channels.  Most other hardware components source from the
+clock generators, but a few (like the ARM or HDMI) will source from
+the PLL dividers directly.
+
+Required properties:
+- compatible:  Should be "brcm,bcm2835-cprman"
+- #clock-cells:Should be <1>. The permitted clock-specifier values can 
be
+ found in include/dt-bindings/clock/bcm2835.h
+- reg: Specifies base physical address and size of the registers
+- clocks:  The external oscillator clock phandle
+
+Example:
+
+   clk_osc: clock@3 {
+   compatible = "fixed-clock";
+   reg = <3>;
+   #clock-cells = <0>;
+   clock-output-names = "osc";
+   clock-frequency = <1920>;
+   };
+
+   clocks: cprman@7e101000 {
+   compatible = "brcm,bcm2835-cprman";
+   #clock-cells = <1>;
+   reg = <0x7e101000 0x2000>;
+   clocks = <&clk_osc>;
+   };
+
+   i2c0: i2c@7e205000 {
+   compatible = "brcm,bcm2835-i2c";
+   reg = <0x7e205000 0x1000>;
+   interrupts = <2 21>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
diff --git a/include/dt-bindings/clock/bcm2835.h 
b/include/dt-bindings/clock/bcm2835.h
new file mode 100644
index 000..d323efa
--- /dev/null
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define BCM2835_PLLA   0
+#define BCM2835_PLLB   1
+#define BCM2835_PLLC   2
+#define BCM2835_PLLD   3
+#define BCM2835_PLLH   4
+
+#define BCM2835_PLLA_CORE  5
+#define BCM2835_PLLA_PER   6
+#define BCM2835_PLLB_ARM   7
+#define BCM2835_PLLC_CORE0 8
+#define BCM2835_PLLC_CORE1 9
+#define BCM2835_PLLC_CORE2 10
+#define BCM2835_PLLC_PER   11
+#define BCM2835_PLLD_CORE  12
+#define BCM2835_PLLD_PER   13
+#define BCM2835_PLLH_RCAL  14
+#define BCM2835_PLLH_AUX   15
+#define BCM2835_PLLH_PIX   16
+
+#define BCM2835_CLOCK_TIMER17
+#define BCM2835_CLOCK_OTP  18
+#define BCM2835_CLOCK_UART 19
+#define BCM2835_CLOCK_VPU  20
+#define BCM2835_CLOCK_V3D  21
+#define BCM2835_CLOCK_ISP  22
+#define BCM2835_CLOCK_H264 23
+#define BCM2835_CLOCK_VEC  24
+#define BCM2835_CLOCK_HSM  25
+#define BCM2835_CLOCK_SDRAM26
+#define BCM2835_CLOCK_TSENS27
+#define BCM2835_CLOCK_EMMC 28
+#define BCM2835_CLOCK_PERI_IMAGE   29
+
+#define BCM2835_CLOCK_COUNT30
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


BCM2835 auxiliary peripheral clocks.

2015-09-10 Thread Eric Anholt
This is a followup to the main audio domain clocks series I just
posted.  There's a clock gate register controlling the clocks for a
few extra peripherals, and Martin Sperl has been working on the SPI
driver for 2/3 of them (the other is a simple UART).  This gives those
drivers the clock gate enable they need to access their registers.

The full series is available for testing at:

https://github.com/anholt/linux/tree/bcm2385-clock-aux

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] clk: bcm2835: Add a driver for the auxiliary peripheral clock gates.

2015-09-10 Thread Eric Anholt
There are a pair of SPI masters and a mini UART that were last minute
additions.  As a result, they didn't get integrated in the same way as
the other gates off of the VPU clock in CPRMAN.

Signed-off-by: Eric Anholt 
---
 drivers/clk/bcm/Makefile  |  1 +
 drivers/clk/bcm/clk-bcm2835-aux.c | 80 +++
 2 files changed, 81 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-bcm2835-aux.c

diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index ee2349b..3082d68 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_CLK_BCM_KONA)  += clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
 obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o 
clk-iproc-asiu.o
 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o
 obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c 
b/drivers/clk/bcm/clk-bcm2835-aux.c
new file mode 100644
index 000..1efa6fb
--- /dev/null
+++ b/drivers/clk/bcm/clk-bcm2835-aux.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int bcm2835_aux_clk_probe(struct platform_device *pdev)
+{
+   struct device *dev = &pdev->dev;
+   struct clk_onecell_data *onecell;
+   const char *parent;
+   struct clk *parent_clk;
+   void __iomem *reg;
+
+   parent_clk = of_clk_get(dev->of_node, 0);
+   if (IS_ERR(parent_clk))
+   return PTR_ERR(parent_clk);
+   parent = __clk_get_name(parent_clk);
+
+   reg = of_iomap(dev->of_node, 0);
+   if (!reg)
+   return -ENODEV;
+
+   onecell = kmalloc(sizeof(*onecell), GFP_KERNEL);
+   if (!onecell)
+   return -ENOMEM;
+   onecell->clk_num = BCM2835_AUX_CLOCK_COUNT;
+   onecell->clks = kzalloc(sizeof(*onecell->clks) *
+   BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL);
+   if (!onecell->clks)
+   return -ENOMEM;
+
+   onecell->clks[BCM2835_AUX_CLOCK_UART] =
+   clk_register_gate(dev, "aux_uart", parent, 0, reg, 0, 0, NULL);
+
+   onecell->clks[BCM2835_AUX_CLOCK_SPI1] =
+   clk_register_gate(dev, "aux_spi1", parent, 0, reg, 1, 0, NULL);
+
+   onecell->clks[BCM2835_AUX_CLOCK_SPI2] =
+   clk_register_gate(dev, "aux_spi2", parent, 0, reg, 2, 0, NULL);
+
+   return of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
+  onecell);
+}
+
+static const struct of_device_id bcm2835_aux_clk_of_match[] = {
+   { .compatible = "brcm,bcm2835-aux-clock", },
+   {},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_aux_clk_of_match);
+
+static struct platform_driver bcm2835_aux_clk_driver = {
+   .driver = {
+   .name = "bcm2835-aux-clk",
+   .of_match_table = bcm2835_aux_clk_of_match,
+   },
+   .probe  = bcm2835_aux_clk_probe,
+};
+builtin_platform_driver(bcm2835_aux_clk_driver);
+
+MODULE_AUTHOR("Eric Anholt ");
+MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] clk: bcm2835: Add bindings for the auxiliary peripheral clock gates.

2015-09-10 Thread Eric Anholt
These will be used for enabling UART1, SPI1, and SPI2.

Signed-off-by: Eric Anholt 
---
 .../bindings/clock/brcm,bcm2835-aux-clock.txt  | 30 ++
 include/dt-bindings/clock/bcm2835-aux.h| 17 
 2 files changed, 47 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt
 create mode 100644 include/dt-bindings/clock/bcm2835-aux.h

diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt 
b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt
new file mode 100644
index 000..f5ce80a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt
@@ -0,0 +1,30 @@
+Broadcom BCM2835 auxiliary peripheral clocks
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+This controls the clock gating for the BCM2835 auxiliary peripherals
+(UART, SPI1, and SPI2).
+
+Required properties:
+- compatible:  Should be "brcm,bcm2835-aux-clock"
+- #clock-cells:Should be <1>. The permitted clock-specifier values can 
be
+ found in include/dt-bindings/clock/bcm2835-aux.h
+- reg: Specifies base physical address and size of the gate register
+- clocks:  The parent clock phandle
+
+Example:
+
+   clocks: cprman@7e101000 {
+   compatible = "brcm,bcm2835-cprman";
+   #clock-cells = <1>;
+   reg = <0x7e101000 0x2000>;
+   clocks = <&clk_osc>;
+   };
+
+   aux_clocks: aux-clocks@0x7e215004 {
+   compatible = "brcm,bcm2835-aux-clock";
+   #clock-cells = <1>;
+   reg = <0x7e215004 0x4>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
+   };
diff --git a/include/dt-bindings/clock/bcm2835-aux.h 
b/include/dt-bindings/clock/bcm2835-aux.h
new file mode 100644
index 000..d91156e
--- /dev/null
+++ b/include/dt-bindings/clock/bcm2835-aux.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define BCM2835_AUX_CLOCK_UART 0
+#define BCM2835_AUX_CLOCK_SPI1 1
+#define BCM2835_AUX_CLOCK_SPI2 2
+#define BCM2835_AUX_CLOCK_COUNT3
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ARM: bcm2835: Add the auxiliary clocks to the device tree.

2015-09-10 Thread Eric Anholt
These will be used for enabling UART1, SPI1, and SPI2.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index a6a55b7..7c37956 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -73,6 +73,13 @@
clocks = <&clk_osc>;
};
 
+   aux_clocks: aux-clocks@0x7e215004 {
+   compatible = "brcm,bcm2835-aux-clock";
+   #clock-cells = <1>;
+   reg = <0x7e215004 0x4>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
+   };
+
rng@7e104000 {
compatible = "brcm,bcm2835-rng";
reg = <0x7e104000 0x10>;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] dmaengine: bcm2835-dma: Convert to use DMA pool

2015-11-24 Thread Eric Anholt
Peter Ujfalusi  writes:

> f93178291712 dmaengine: bcm2835-dma: Fix memory leak when stopping a
>running transfer
>
> Fixed the memleak, but introduced another issue: the terminate_all callback
> might be called with interrupts disabled and the dma_free_coherent() is
> not allowed to be called when IRQs are disabled.
> Convert the driver to use dma_pool_* for managing the list of control
> blocks for the transfer.
>
> Fixes: f93178291712 ("dmaengine: bcm2835-dma: Fix memory leak when stopping a 
> running transfer")
> Signed-off-by: Peter Ujfalusi 

It sounds like you got positive testing feedback.  Using the DMA pool
for our bcm2835_dma_cbs makes sense to me, too.

Reviewed-by: Eric Anholt 


signature.asc
Description: PGP signature


Re: [PATCH 3/9] drm/vc4: Add create and map BO ioctls.

2015-12-07 Thread Eric Anholt
Michel Dänzer  writes:

> On 08.12.2015 10:16, Eric Anholt wrote:
>> Emil Velikov  writes:
>> 
>>> Hi Eric,
>>>
>>> A couple of suggestions/requests on the UAPI header side
>>>
>>> On 1 December 2015 at 20:35, Eric Anholt  wrote:
>>>
>>>> --- /dev/null
>>>> +++ b/include/uapi/drm/vc4_drm.h
>>>
>>>> +#include 
>>>> +
>>> Can we make this a "drm.h" ?
>> 
>> Nope.
>> 
>> include/uapi/drm/vc4_drm.h:27:17: fatal error: drm.h: No such file or 
>> directory
>
> What happened to include/uapi/drm/drm.h in that tree?

Looks like it's just  versus "drm.h" failure.  I've changed over
to "drm.h"



signature.asc
Description: PGP signature


Re: [PATCH v3 4/4] clk: bcm2835: Add PWM clock support to the device tree

2015-12-07 Thread Eric Anholt
Stefan Wahren  writes:

> Hi Remi,
>
> Am 07.12.2015 um 19:17 schrieb Remi Pommarel:
>> Hi Stefan,
>>
>> On Sun, Dec 06, 2015 at 10:16:25PM +0100, Stefan Wahren wrote:
>>> Hi Remi,
>>>
>>> please send this patch to devicet...@vger.kernel.org.
>>
>> Ok, just to be sure I understand the process here. I should resend a new
>> version of the whole patchset including the devicetree mailing list as
>> recipent. Then the first 3 patches will eventually get pushed by a clock
>> subsystem maintainer. And finally this last patch will be pushed by a
>> devicetree maintainer.
>>
>> Am I right here ?
>
> sorry for the confusion. I mean that you send a copy to 
> devicet...@vger.kernel.org so subscribers have a chance to review.
>
> I'm not sure but according to your subject you suggest that this dts 
> patch should go through clock subsystem which isn't optimal. This should 
> be better applied by Stephen or Eric.

It would be applied by me, but that's for me to worry about, not the
patch submitter.  The subject prefix would be "ARM: bcm2835: ", but
that's trivial for me to fix when applying, not the kind of thing worth
asking for a respin for.


signature.asc
Description: PGP signature


[PATCH v2 0/9] VC4 3D rendering support.

2015-12-08 Thread Eric Anholt
Updated version of the patch series for Emil's comments about
vc4_drm.h.  I also pulled in some improvements to the validation code
which I'd written in Mesa and failed to propagate to this branch.

The series can be found at:

https://github.com/anholt/linux/tree/vc4-kms-v3d-squash-2

and a version for booting and testing can be found at:

https://github.com/anholt/linux/tree/vc4-kms-v3d-squash-2-boot

Eric Anholt (9):
  drm: Create a driver hook for allocating GEM object structs.
  drm/vc4: Add a BO cache.
  drm/vc4: Add create and map BO ioctls.
  drm/vc4: Add an API for creating GPU shaders in GEM BOs.
  drm/vc4: Fix a typo in a V3D debug register.
  drm/vc4: Bind and initialize the V3D engine.
  drm/vc4: Add support for drawing 3D frames.
  drm/vc4: Add support for async pageflips.
  drm/vc4: Add an interface for capturing the GPU state after a hang.

 drivers/gpu/drm/drm_gem_cma_helper.c   |  10 +-
 drivers/gpu/drm/vc4/Makefile   |  11 +-
 drivers/gpu/drm/vc4/vc4_bo.c   | 517 -
 drivers/gpu/drm/vc4/vc4_crtc.c |  99 +++-
 drivers/gpu/drm/vc4/vc4_debugfs.c  |   3 +
 drivers/gpu/drm/vc4/vc4_drv.c  |  36 +-
 drivers/gpu/drm/vc4/vc4_drv.h  | 318 +-
 drivers/gpu/drm/vc4/vc4_gem.c  | 867 +++
 drivers/gpu/drm/vc4/vc4_irq.c  | 210 +++
 drivers/gpu/drm/vc4/vc4_kms.c  | 149 -
 drivers/gpu/drm/vc4/vc4_packet.h   | 399 +
 drivers/gpu/drm/vc4/vc4_plane.c|  40 ++
 drivers/gpu/drm/vc4/vc4_qpu_defines.h  | 264 +
 drivers/gpu/drm/vc4/vc4_regs.h |   2 +-
 drivers/gpu/drm/vc4/vc4_render_cl.c| 634 
 drivers/gpu/drm/vc4/vc4_trace.h|  63 ++
 drivers/gpu/drm/vc4/vc4_trace_points.c |  14 +
 drivers/gpu/drm/vc4/vc4_v3d.c  | 262 +
 drivers/gpu/drm/vc4/vc4_validate.c | 900 +
 drivers/gpu/drm/vc4/vc4_validate_shaders.c | 513 
 include/drm/drmP.h |   7 +
 include/uapi/drm/Kbuild|   1 +
 include/uapi/drm/vc4_drm.h | 279 +
 23 files changed, 5577 insertions(+), 21 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_gem.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_irq.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_packet.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_qpu_defines.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_render_cl.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace_points.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_v3d.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate_shaders.c
 create mode 100644 include/uapi/drm/vc4_drm.h

-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/9] drm: Create a driver hook for allocating GEM object structs.

2015-12-08 Thread Eric Anholt
The CMA helpers had no way for a driver to extend the struct with its
own fields.  Since the CMA helpers are mostly "Allocate a
drm_gem_cma_object, then fill in a few fields", it's hard to write as
pure helpers without passing in a driver callback for the allocate
step.

Signed-off-by: Eric Anholt 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_gem_cma_helper.c | 10 ++
 include/drm/drmP.h   |  7 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index e109b49..0f7b00ba 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -59,11 +59,13 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size)
struct drm_gem_object *gem_obj;
int ret;
 
-   cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
-   if (!cma_obj)
+   if (drm->driver->gem_create_object)
+   gem_obj = drm->driver->gem_create_object(drm, size);
+   else
+   gem_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+   if (!gem_obj)
return ERR_PTR(-ENOMEM);
-
-   gem_obj = &cma_obj->base;
+   cma_obj = container_of(gem_obj, struct drm_gem_cma_object, base);
 
ret = drm_gem_object_init(drm, gem_obj, size);
if (ret)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 0b921ae..22ff162 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -580,6 +580,13 @@ struct drm_driver {
int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
 
+   /**
+* Hook for allocating the GEM object struct, for use by core
+* helpers.
+*/
+   struct drm_gem_object *(*gem_create_object)(struct drm_device *dev,
+   size_t size);
+
/* prime: */
/* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file 
*file_priv,
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/9] drm/vc4: Add a BO cache.

2015-12-08 Thread Eric Anholt
We need to allocate new BOs in the kernel as part of each frame, but
the CMA allocator is way too slow for that.  As an optimization, keep
track of recently-freed BOs and reuse them, with a 1 second timeout to
fully free them back to the system.

This improves 3D performance by about 15%.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_bo.c  | 336 +-
 drivers/gpu/drm/vc4/vc4_debugfs.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.c |   6 +-
 drivers/gpu/drm/vc4/vc4_drv.h |  49 +-
 4 files changed, 384 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index ab9f510..18faa5b 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -12,19 +12,229 @@
  * access to system memory with no MMU in between.  To support it, we
  * use the GEM CMA helper functions to allocate contiguous ranges of
  * physical memory for our BOs.
+ *
+ * Since the CMA allocator is very slow, we keep a cache of recently
+ * freed BOs around so that the kernel's allocation of objects for 3D
+ * rendering can return quickly.
  */
 
 #include "vc4_drv.h"
 
-struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
+static void vc4_bo_stats_dump(struct vc4_dev *vc4)
+{
+   DRM_INFO("num bos allocated: %d\n",
+vc4->bo_stats.num_allocated);
+   DRM_INFO("size bos allocated: %dkb\n",
+vc4->bo_stats.size_allocated / 1024);
+   DRM_INFO("num bos used: %d\n",
+vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached);
+   DRM_INFO("size bos used: %dkb\n",
+(vc4->bo_stats.size_allocated -
+ vc4->bo_stats.size_cached) / 1024);
+   DRM_INFO("num bos cached: %d\n",
+vc4->bo_stats.num_cached);
+   DRM_INFO("size bos cached: %dkb\n",
+vc4->bo_stats.size_cached / 1024);
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
+{
+   struct drm_info_node *node = (struct drm_info_node *)m->private;
+   struct drm_device *dev = node->minor->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_bo_stats stats;
+
+   /* Take a snapshot of the current stats with the lock held. */
+   mutex_lock(&vc4->bo_lock);
+   stats = vc4->bo_stats;
+   mutex_unlock(&vc4->bo_lock);
+
+   seq_printf(m, "num bos allocated: %d\n",
+  stats.num_allocated);
+   seq_printf(m, "size bos allocated: %dkb\n",
+  stats.size_allocated / 1024);
+   seq_printf(m, "num bos used: %d\n",
+  stats.num_allocated - stats.num_cached);
+   seq_printf(m, "size bos used: %dkb\n",
+  (stats.size_allocated - stats.size_cached) / 1024);
+   seq_printf(m, "num bos cached: %d\n",
+  stats.num_cached);
+   seq_printf(m, "size bos cached: %dkb\n",
+  stats.size_cached / 1024);
+
+   return 0;
+}
+#endif
+
+static uint32_t bo_page_index(size_t size)
+{
+   return (size / PAGE_SIZE) - 1;
+}
+
+/* Must be called with bo_lock held. */
+static void vc4_bo_destroy(struct vc4_bo *bo)
 {
+   struct drm_gem_object *obj = &bo->base.base;
+   struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+
+   vc4->bo_stats.num_allocated--;
+   vc4->bo_stats.size_allocated -= obj->size;
+   drm_gem_cma_free_object(obj);
+}
+
+/* Must be called with bo_lock held. */
+static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
+{
+   struct drm_gem_object *obj = &bo->base.base;
+   struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+
+   vc4->bo_stats.num_cached--;
+   vc4->bo_stats.size_cached -= obj->size;
+
+   list_del(&bo->unref_head);
+   list_del(&bo->size_head);
+}
+
+static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev,
+size_t size)
+{
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   uint32_t page_index = bo_page_index(size);
+
+   if (vc4->bo_cache.size_list_size <= page_index) {
+   uint32_t new_size = max(vc4->bo_cache.size_list_size * 2,
+   page_index + 1);
+   struct list_head *new_list;
+   uint32_t i;
+
+   new_list = kmalloc_array(new_size, sizeof(struct list_head),
+GFP_KERNEL);
+   if (!new_list)
+   return NULL;
+
+   /* Rebase the old cached BO lists to their new list
+* head locations.
+*/
+   for (i = 0; i < vc4->bo_cache.size_list_size; i++) {
+   

[PATCH v2 3/9] drm/vc4: Add create and map BO ioctls.

2015-12-08 Thread Eric Anholt
While there exist dumb APIs for creating and mapping BOs, one of the
rules is that drivers doing 3D acceleration have to provide their own
APIs for buffer allocation (besides, the pitch/height parameters of
the dumb alloc don't really make sense for a lot of 3D allocations).

Signed-off-by: Eric Anholt 
---

v2: Use __u32-style types, use "drm.h" instead of .

 drivers/gpu/drm/vc4/vc4_bo.c  | 41 ++
 drivers/gpu/drm/vc4/vc4_drv.c |  3 ++
 drivers/gpu/drm/vc4/vc4_drv.h |  4 +++
 include/uapi/drm/Kbuild   |  1 +
 include/uapi/drm/vc4_drm.h| 68 +++
 5 files changed, 117 insertions(+)
 create mode 100644 include/uapi/drm/vc4_drm.h

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 18faa5b..06cba26 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -19,6 +19,7 @@
  */
 
 #include "vc4_drv.h"
+#include "uapi/drm/vc4_drm.h"
 
 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 {
@@ -346,6 +347,46 @@ static void vc4_bo_cache_time_timer(unsigned long data)
schedule_work(&vc4->bo_cache.time_work);
 }
 
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_priv)
+{
+   struct drm_vc4_create_bo *args = data;
+   struct vc4_bo *bo = NULL;
+   int ret;
+
+   /*
+* We can't allocate from the BO cache, because the BOs don't
+* get zeroed, and that might leak data between users.
+*/
+   bo = vc4_bo_create(dev, args->size, false);
+   if (!bo)
+   return -ENOMEM;
+
+   ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
+   drm_gem_object_unreference_unlocked(&bo->base.base);
+
+   return ret;
+}
+
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+   struct drm_vc4_mmap_bo *args = data;
+   struct drm_gem_object *gem_obj;
+
+   gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+   if (!gem_obj) {
+   DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+   return -EINVAL;
+   }
+
+   /* The mmap offset was set up at BO allocation time. */
+   args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
+
+   drm_gem_object_unreference_unlocked(gem_obj);
+   return 0;
+}
+
 void vc4_bo_cache_init(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index da041fa..5fa4688 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -16,6 +16,7 @@
 #include 
 #include "drm_fb_cma_helper.h"
 
+#include "uapi/drm/vc4_drm.h"
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -73,6 +74,8 @@ static const struct file_operations vc4_drm_fops = {
 };
 
 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+   DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
 };
 
 static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 39a1ff5..fddb0a0 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -155,6 +155,10 @@ int vc4_dumb_create(struct drm_file *file_priv,
struct drm_mode_create_dumb *args);
 struct dma_buf *vc4_prime_export(struct drm_device *dev,
 struct drm_gem_object *obj, int flags);
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_priv);
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
 void vc4_bo_cache_init(struct drm_device *dev);
 void vc4_bo_cache_destroy(struct drm_device *dev);
 int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
index 38d4370..974fcd5 100644
--- a/include/uapi/drm/Kbuild
+++ b/include/uapi/drm/Kbuild
@@ -17,4 +17,5 @@ header-y += tegra_drm.h
 header-y += via_drm.h
 header-y += vmwgfx_drm.h
 header-y += msm_drm.h
+header-y += vc4_drm.h
 header-y += virtgpu_drm.h
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
new file mode 100644
index 000..219d34c
--- /dev/null
+++ b/include/uapi/drm/vc4_drm.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2014-2015 Broadcom
+ *
+ * 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

[PATCH v2 5/9] drm/vc4: Fix a typo in a V3D debug register.

2015-12-08 Thread Eric Anholt
Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 9e4e904..4e52a0a 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -154,7 +154,7 @@
 #define V3D_PCTRS14  0x006f4
 #define V3D_PCTR15   0x006f8
 #define V3D_PCTRS15  0x006fc
-#define V3D_BGE  0x00f00
+#define V3D_DBGE 0x00f00
 #define V3D_FDBGO0x00f04
 #define V3D_FDBGB0x00f08
 #define V3D_FDBGR0x00f0c
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/9] drm/vc4: Add an API for creating GPU shaders in GEM BOs.

2015-12-08 Thread Eric Anholt
Since we have no MMU, the kernel needs to validate that the submitted
shader code won't make any accesses to memory that the user doesn't
control, which involves banning some operations (general purpose DMA
writes), and tracking where we need to write out pointers for other
operations (texture sampling).  Once it's validated, we return a GEM
BO containing the shader, which doesn't allow mapping for write or
exporting to other subsystems.

Signed-off-by: Eric Anholt 
---

v2: Use __u32-style types.

 drivers/gpu/drm/vc4/Makefile   |   3 +-
 drivers/gpu/drm/vc4/vc4_bo.c   | 140 
 drivers/gpu/drm/vc4/vc4_drv.c  |   9 +-
 drivers/gpu/drm/vc4/vc4_drv.h  |  50 +++
 drivers/gpu/drm/vc4/vc4_qpu_defines.h  | 264 +++
 drivers/gpu/drm/vc4/vc4_validate_shaders.c | 513 +
 include/uapi/drm/vc4_drm.h |  25 ++
 7 files changed, 999 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_qpu_defines.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate_shaders.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 32b4f9c..eb776a6 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -10,7 +10,8 @@ vc4-y := \
vc4_kms.o \
vc4_hdmi.o \
vc4_hvs.o \
-   vc4_plane.o
+   vc4_plane.o \
+   vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
 
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 06cba26..18dfe3e 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -79,6 +79,12 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
struct drm_gem_object *obj = &bo->base.base;
struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
 
+   if (bo->validated_shader) {
+   kfree(bo->validated_shader->texture_samples);
+   kfree(bo->validated_shader);
+   bo->validated_shader = NULL;
+   }
+
vc4->bo_stats.num_allocated--;
vc4->bo_stats.size_allocated -= obj->size;
drm_gem_cma_free_object(obj);
@@ -315,6 +321,12 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
goto out;
}
 
+   if (bo->validated_shader) {
+   kfree(bo->validated_shader->texture_samples);
+   kfree(bo->validated_shader);
+   bo->validated_shader = NULL;
+   }
+
bo->free_time = jiffies;
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
@@ -347,6 +359,78 @@ static void vc4_bo_cache_time_timer(unsigned long data)
schedule_work(&vc4->bo_cache.time_work);
 }
 
+struct dma_buf *
+vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader) {
+   DRM_ERROR("Attempting to export shader BO\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   return drm_gem_prime_export(dev, obj, flags);
+}
+
+int vc4_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+   struct drm_gem_object *gem_obj;
+   struct vc4_bo *bo;
+   int ret;
+
+   ret = drm_gem_mmap(filp, vma);
+   if (ret)
+   return ret;
+
+   gem_obj = vma->vm_private_data;
+   bo = to_vc4_bo(gem_obj);
+
+   if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
+   DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+   return -EINVAL;
+   }
+
+   /*
+* Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the
+* vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map
+* the whole buffer.
+*/
+   vma->vm_flags &= ~VM_PFNMAP;
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma,
+   bo->base.vaddr, bo->base.paddr,
+   vma->vm_end - vma->vm_start);
+   if (ret)
+   drm_gem_vm_close(vma);
+
+   return ret;
+}
+
+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
+   DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+   return -EINVAL;
+   }
+
+   return drm_gem_cma_prime_mmap(obj, vma);
+}
+
+void *vc4_prime_vmap(struct drm_gem_object *obj)
+{
+   struct vc4_bo *bo = to_vc4_bo(obj);
+
+   if (bo->validated_shader) {
+   DRM_ERROR("mmaping of shader BOs not allowed.\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+

[PATCH v2 9/9] drm/vc4: Add an interface for capturing the GPU state after a hang.

2015-12-08 Thread Eric Anholt
This can be parsed with vc4-gpu-tools tools for trying to figure out
what was going on.

Signed-off-by: Eric Anholt 
---

v2: Use __u32-style types.

 drivers/gpu/drm/vc4/vc4_drv.c |   2 +
 drivers/gpu/drm/vc4/vc4_drv.h |   4 +
 drivers/gpu/drm/vc4/vc4_gem.c | 185 ++
 include/uapi/drm/vc4_drm.h|  45 ++
 4 files changed, 236 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 2cfee59..97226b6 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -80,6 +80,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
+ DRM_ROOT_ONLY),
 };
 
 static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index f9927d8..080865e 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -19,6 +19,8 @@ struct vc4_dev {
 
struct drm_fbdev_cma *fbdev;
 
+   struct vc4_hang_state *hang_state;
+
/* The kernel-space BO cache.  Tracks buffers that have been
 * unreferenced by all other users (refcounts of 0!) but not
 * yet freed, so we can do cheap allocations.
@@ -361,6 +363,8 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_priv);
 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv);
+int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv);
 int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
 int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 void *vc4_prime_vmap(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 5fb0556..39f29e7 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -40,6 +40,186 @@ vc4_queue_hangcheck(struct drm_device *dev)
  round_jiffies_up(jiffies + msecs_to_jiffies(100)));
 }
 
+struct vc4_hang_state {
+   struct drm_vc4_get_hang_state user_state;
+
+   u32 bo_count;
+   struct drm_gem_object **bo;
+};
+
+static void
+vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state)
+{
+   unsigned int i;
+
+   mutex_lock(&dev->struct_mutex);
+   for (i = 0; i < state->user_state.bo_count; i++)
+   drm_gem_object_unreference(state->bo[i]);
+   mutex_unlock(&dev->struct_mutex);
+
+   kfree(state);
+}
+
+int
+vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file_priv)
+{
+   struct drm_vc4_get_hang_state *get_state = data;
+   struct drm_vc4_get_hang_state_bo *bo_state;
+   struct vc4_hang_state *kernel_state;
+   struct drm_vc4_get_hang_state *state;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   unsigned long irqflags;
+   u32 i;
+   int ret;
+
+   spin_lock_irqsave(&vc4->job_lock, irqflags);
+   kernel_state = vc4->hang_state;
+   if (!kernel_state) {
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+   return -ENOENT;
+   }
+   state = &kernel_state->user_state;
+
+   /* If the user's array isn't big enough, just return the
+* required array size.
+*/
+   if (get_state->bo_count < state->bo_count) {
+   get_state->bo_count = state->bo_count;
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+   return 0;
+   }
+
+   vc4->hang_state = NULL;
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
+   /* Save the user's BO pointer, so we don't stomp it with the memcpy. */
+   state->bo = get_state->bo;
+   memcpy(get_state, state, sizeof(*state));
+
+   bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL);
+   if (!bo_state) {
+   ret = -ENOMEM;
+   goto err_free;
+   }
+
+   for (i = 0; i < state->bo_count; i++) {
+   struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]);
+   u32 handle;
+
+   ret = drm_gem_handle_create(file_priv, kernel_state->bo[i],
+   &handle);
+
+   if (ret) {
+   state->bo_count = i - 1;
+   goto err;
+   }
+   bo_state[i].handle = handle;
+   bo_state[i].paddr = vc4_bo->base.paddr;
+  

[PATCH v2 6/9] drm/vc4: Bind and initialize the V3D engine.

2015-12-08 Thread Eric Anholt
This is the component of the GPU that does 3D rendering.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/Makefile  |   1 +
 drivers/gpu/drm/vc4/vc4_debugfs.c |   2 +
 drivers/gpu/drm/vc4/vc4_drv.c |   1 +
 drivers/gpu/drm/vc4/vc4_drv.h |  13 +++
 drivers/gpu/drm/vc4/vc4_v3d.c | 225 ++
 5 files changed, 242 insertions(+)
 create mode 100644 drivers/gpu/drm/vc4/vc4_v3d.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index eb776a6..e87a6f2 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -11,6 +11,7 @@ vc4-y := \
vc4_hdmi.o \
vc4_hvs.o \
vc4_plane.o \
+   vc4_v3d.o \
vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c 
b/drivers/gpu/drm/vc4/vc4_debugfs.c
index 6bcf96e..d76ad10 100644
--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -22,6 +22,8 @@ static const struct drm_info_list vc4_debugfs_list[] = {
{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
+   {"v3d_ident", vc4_v3d_debugfs_ident, 0},
+   {"v3d_regs", vc4_v3d_debugfs_regs, 0},
 };
 
 #define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index da4be9c..db58d74 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -236,6 +236,7 @@ static struct platform_driver *const component_drivers[] = {
&vc4_hdmi_driver,
&vc4_crtc_driver,
&vc4_hvs_driver,
+   &vc4_v3d_driver,
 };
 
 static int vc4_platform_drm_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index bd77d55..8945463 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -15,6 +15,7 @@ struct vc4_dev {
struct vc4_hdmi *hdmi;
struct vc4_hvs *hvs;
struct vc4_crtc *crtc[3];
+   struct vc4_v3d *v3d;
 
struct drm_fbdev_cma *fbdev;
 
@@ -82,6 +83,11 @@ to_vc4_bo(struct drm_gem_object *bo)
return (struct vc4_bo *)bo;
 }
 
+struct vc4_v3d {
+   struct platform_device *pdev;
+   void __iomem *regs;
+};
+
 struct vc4_hvs {
struct platform_device *pdev;
void __iomem *regs;
@@ -119,6 +125,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
return container_of(encoder, struct vc4_encoder, base);
 }
 
+#define V3D_READ(offset) readl(vc4->v3d->regs + offset)
+#define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset)
 #define HVS_READ(offset) readl(vc4->hvs->regs + offset)
 #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
 
@@ -241,6 +249,11 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
 u32 vc4_plane_dlist_size(struct drm_plane_state *state);
 
+/* vc4_v3d.c */
+extern struct platform_driver vc4_v3d_driver;
+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
+
 /* vc4_validate_shader.c */
 struct vc4_validated_shader_info *
 vc4_validate_shader(struct drm_gem_cma_object *shader_obj);
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
new file mode 100644
index 000..040ad0d
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#ifdef CONFIG_DEBUG_FS
+#define REGDEF(reg) { reg, #reg }
+static const struct {
+   uint32_t reg;
+   const char *name;
+} vc4_reg_defs[] = {
+   REGDEF(V3D_IDENT0),
+   REGDEF(V3D_IDENT1),
+   REGDEF(V3D_IDENT2),
+   REGDEF(V3D_SCRATCH),
+   REGDEF(V3D_L2CACTL),
+   REGDEF(V3D_SLCACTL),
+   REGDEF(V3D_INTCTL),
+   REGDEF(V3D_INTENA),
+   REGDEF(V3D_INTDIS),
+   REGDEF(V3D_CT0CS),
+ 

[PATCH v2 8/9] drm/vc4: Add support for async pageflips.

2015-12-08 Thread Eric Anholt
An async pageflip stores the modeset to be done and executes it once
the BOs are ready to be displayed.  This gets us about 3x performance
in full screen rendering with pageflipping.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c  |  99 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  16 +
 drivers/gpu/drm/vc4/vc4_gem.c   |  40 +++
 drivers/gpu/drm/vc4/vc4_kms.c   | 149 +++-
 drivers/gpu/drm/vc4/vc4_plane.c |  40 +++
 5 files changed, 342 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 7a9f476..a319332 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -35,6 +35,7 @@
 #include "drm_atomic_helper.h"
 #include "drm_crtc_helper.h"
 #include "linux/clk.h"
+#include "drm_fb_cma_helper.h"
 #include "linux/component.h"
 #include "linux/of_device.h"
 #include "vc4_drv.h"
@@ -475,10 +476,106 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void 
*data)
return ret;
 }
 
+struct vc4_async_flip_state {
+   struct drm_crtc *crtc;
+   struct drm_framebuffer *fb;
+   struct drm_pending_vblank_event *event;
+
+   struct vc4_seqno_cb cb;
+};
+
+/* Called when the V3D execution for the BO being flipped to is done, so that
+ * we can actually update the plane's address to point to it.
+ */
+static void
+vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
+{
+   struct vc4_async_flip_state *flip_state =
+   container_of(cb, struct vc4_async_flip_state, cb);
+   struct drm_crtc *crtc = flip_state->crtc;
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct drm_plane *plane = crtc->primary;
+
+   vc4_plane_async_set_fb(plane, flip_state->fb);
+   if (flip_state->event) {
+   unsigned long flags;
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+   drm_crtc_send_vblank_event(crtc, flip_state->event);
+   spin_unlock_irqrestore(&dev->event_lock, flags);
+   }
+
+   drm_framebuffer_unreference(flip_state->fb);
+   kfree(flip_state);
+
+   up(&vc4->async_modeset);
+}
+
+/* Implements async (non-vblank-synced) page flips.
+ *
+ * The page flip ioctl needs to return immediately, so we grab the
+ * modeset semaphore on the pipe, and queue the address update for
+ * when V3D is done with the BO being flipped to.
+ */
+static int vc4_async_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
+{
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct drm_plane *plane = crtc->primary;
+   int ret = 0;
+   struct vc4_async_flip_state *flip_state;
+   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
+   struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
+
+   flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
+   if (!flip_state)
+   return -ENOMEM;
+
+   drm_framebuffer_reference(fb);
+   flip_state->fb = fb;
+   flip_state->crtc = crtc;
+   flip_state->event = event;
+
+   /* Make sure all other async modesetes have landed. */
+   ret = down_interruptible(&vc4->async_modeset);
+   if (ret) {
+   kfree(flip_state);
+   return ret;
+   }
+
+   /* Immediately update the plane's legacy fb pointer, so that later
+* modeset prep sees the state that will be present when the semaphore
+* is released.
+*/
+   drm_atomic_set_fb_for_plane(plane->state, fb);
+   plane->fb = fb;
+
+   vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno,
+  vc4_async_page_flip_complete);
+
+   /* Driver takes ownership of state on successful async commit. */
+   return 0;
+}
+
+static int vc4_page_flip(struct drm_crtc *crtc,
+struct drm_framebuffer *fb,
+struct drm_pending_vblank_event *event,
+uint32_t flags)
+{
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
+   return vc4_async_page_flip(crtc, fb, event, flags);
+   else
+   return drm_atomic_helper_page_flip(crtc, fb, event, flags);
+}
+
 static const struct drm_crtc_funcs vc4_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = vc4_crtc_destroy,
-   .page_flip = drm_atomic_helper_page_flip,
+   .page_flip = vc4_page_flip,
.set_property = NULL,
.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
.cursor_move = NULL, /* handled by drm_mode_cur

[PATCH v2 7/9] drm/vc4: Add support for drawing 3D frames.

2015-12-08 Thread Eric Anholt
The user submission is basically a pointer to a command list and a
pointer to uniforms.  We copy those in to the kernel, validate and
relocate them, and store the result in a GPU BO which we queue for
execution.

Signed-off-by: Eric Anholt 
---

v2: Drop support for NV shader recs (not necessary for GL), simplify
vc4_use_bo(), improve bin flush/semaphore checks, use __u32 style
types.

 drivers/gpu/drm/vc4/Makefile   |   7 +
 drivers/gpu/drm/vc4/vc4_drv.c  |  15 +-
 drivers/gpu/drm/vc4/vc4_drv.h  | 182 +++
 drivers/gpu/drm/vc4/vc4_gem.c  | 642 +++
 drivers/gpu/drm/vc4/vc4_irq.c  | 210 
 drivers/gpu/drm/vc4/vc4_packet.h   | 399 +++
 drivers/gpu/drm/vc4/vc4_render_cl.c| 634 +++
 drivers/gpu/drm/vc4/vc4_trace.h|  63 +++
 drivers/gpu/drm/vc4/vc4_trace_points.c |  14 +
 drivers/gpu/drm/vc4/vc4_v3d.c  |  37 ++
 drivers/gpu/drm/vc4/vc4_validate.c | 900 +
 include/uapi/drm/vc4_drm.h | 141 ++
 12 files changed, 3243 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_gem.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_irq.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_packet.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_render_cl.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_trace_points.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_validate.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index e87a6f2..4c6a99f 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -8,12 +8,19 @@ vc4-y := \
vc4_crtc.o \
vc4_drv.o \
vc4_kms.o \
+   vc4_gem.o \
vc4_hdmi.o \
vc4_hvs.o \
+   vc4_irq.o \
vc4_plane.o \
+   vc4_render_cl.o \
+   vc4_trace_points.o \
vc4_v3d.o \
+   vc4_validate.o \
vc4_validate_shaders.o
 
 vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
 
 obj-$(CONFIG_DRM_VC4)  += vc4.o
+
+CFLAGS_vc4_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index db58d74..2cfee59 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -74,6 +74,9 @@ static const struct file_operations vc4_drm_fops = {
 };
 
 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+   DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0),
+   DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
@@ -83,10 +86,16 @@ static struct drm_driver vc4_drm_driver = {
.driver_features = (DRIVER_MODESET |
DRIVER_ATOMIC |
DRIVER_GEM |
+   DRIVER_HAVE_IRQ |
DRIVER_PRIME),
.lastclose = vc4_lastclose,
.preclose = vc4_drm_preclose,
 
+   .irq_handler = vc4_irq,
+   .irq_preinstall = vc4_irq_preinstall,
+   .irq_postinstall = vc4_irq_postinstall,
+   .irq_uninstall = vc4_irq_uninstall,
+
.enable_vblank = vc4_enable_vblank,
.disable_vblank = vc4_disable_vblank,
.get_vblank_counter = drm_vblank_count,
@@ -181,9 +190,11 @@ static int vc4_drm_bind(struct device *dev)
if (ret)
goto unref;
 
+   vc4_gem_init(drm);
+
ret = component_bind_all(dev, drm);
if (ret)
-   goto unref;
+   goto gem_destroy;
 
ret = drm_dev_register(drm, 0);
if (ret < 0)
@@ -207,6 +218,8 @@ unregister:
drm_dev_unregister(drm);
 unbind_all:
component_unbind_all(dev, drm);
+gem_destroy:
+   vc4_gem_destroy(drm);
 unref:
drm_dev_unref(drm);
vc4_bo_cache_destroy(drm);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 8945463..0bc8c57 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -49,6 +49,48 @@ struct vc4_dev {
 
/* Protects bo_cache and the BO stats. */
struct mutex bo_lock;
+
+   /* Sequence number for the last job queued in job_list.
+* Starts at 0 (no jobs emitted).
+*/
+   uint64_t emit_seqno;
+
+   /* Sequence number for the last completed job on the GPU.
+* Starts at 0 (no jobs completed).
+*/
+   uint64_t finished_seqno;
+
+   /* List of all struct vc4_exec_info for jobs to be executed.
+* The first job in the list is the one currently programmed
+* into ct0ca/ct1ca for execution.
+*/
+   struct list_head job_list;
+   /* List of the finished vc4_exec_infos waiting to be freed

[PATCH v4 1/8] clk: bcm2835: Add binding docs for the Raspberry Pi clock provider

2015-07-20 Thread Eric Anholt
The hardware clocks are not controllable by the ARM, so we have to
make requests to the firmware to do so from the VPU side.  This will
let us replace fixed clocks in our DT with actual clock control (and
correct frequency information).

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
Acked-by: Lee Jones 
---

v2: Include the dt-bindings header in this commit instead of the next
one.  Make the clock indices match the firmware clock IDs.  Rename
the binding's compat string.  Move the firmware phandle to be
under a vendor-specific namespace.
v4: Mention 'clk' in the subject instead of the more generic
dt/bindings.

 .../clock/raspberrypi,bcm2835-firmware-clocks.txt  | 25 ++
 include/dt-bindings/clk/raspberrypi.h  | 23 
 2 files changed, 48 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
 create mode 100644 include/dt-bindings/clk/raspberrypi.h

diff --git 
a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
 
b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
new file mode 100644
index 000..0972602
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
@@ -0,0 +1,25 @@
+Raspberry Pi firmware clock provider.
+
+The Raspberry Pi architecture doesn't provide direct access to the
+CLOCKMAN peripheral from the ARM side, so Linux has to make requests
+to the VPU firmware to program them.
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible:  Should be "raspberrypi,bcm2835-firmware-clocks"
+
+- #clock-cells:Shall have value <1>.  The permitted 
clock-specifier
+ values can be found in
+ include/dt-bindings/clk/raspberrypi.h.
+
+- raspberrypi,firmware:Phandle to the firmware driver node.
+
+Example:
+
+firmware_clocks: firmware-clocks {
+   compatible = "raspberrypi,bcm2835-firmware-clocks";
+   #clock-cells = <1>;
+   raspberrypi,firmware = <&firmware>;
+};
diff --git a/include/dt-bindings/clk/raspberrypi.h 
b/include/dt-bindings/clk/raspberrypi.h
new file mode 100644
index 000..ceec90f
--- /dev/null
+++ b/include/dt-bindings/clk/raspberrypi.h
@@ -0,0 +1,23 @@
+#/*
+ *  Copyright ?? 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DT_BINDINGS_CLK_RASPBERRYPI_H
+#define _DT_BINDINGS_CLK_RASPBERRYPI_H
+
+#define RPI_CLOCK_EMMC 1
+#define RPI_CLOCK_UART02
+#define RPI_CLOCK_ARM  3
+#define RPI_CLOCK_CORE 4
+#define RPI_CLOCK_V3D  5
+#define RPI_CLOCK_H264 6
+#define RPI_CLOCK_ISP  7
+#define RPI_CLOCK_SDRAM8
+#define RPI_CLOCK_PIXEL9
+#define RPI_CLOCK_PWM  10
+
+#endif
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 0/8] Raspberry Pi clock support

2015-07-20 Thread Eric Anholt
This is a respin of my rpi-dt-clocks series (also available at
https://github.com/anholt/linux/tree/rpi-dt-clocks).  New in this
version is mentioning the clk subsystem for drivers/clk/* patches,
some better documentation of behavior in clk-raspberrypi.c, and a new
patch at the tail of the series for updating the EMMC clock.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 6/8] ARM: bcm2835: Use the RPi firmware clocks for uart.

2015-07-20 Thread Eric Anholt
This gets us a correct apb_pclk, which previously was accidentally
using the "20201000.uart" clock from clk-bcm2835.c, due to the
fallback clk_get_sys() path.

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 7 +++
 arch/arm/boot/dts/bcm2835.dtsi | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 7cc47fb..9549eb8 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,3 +1,4 @@
+#include 
 #include "bcm2835.dtsi"
 
 / {
@@ -62,3 +63,9 @@
status = "okay";
bus-width = <4>;
 };
+
+&uart0 {
+   clocks = <&firmware_clocks RPI_CLOCK_UART0>,
+<&firmware_clocks RPI_CLOCK_CORE>;
+   clock-names = "uartclk", "apb_pclk";
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 32f5830..5be2862 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -92,7 +92,7 @@
#interrupt-cells = <2>;
};
 
-   uart@7e201000 {
+   uart0: uart@7e201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", 
"arm,primecell";
reg = <0x7e201000 0x1000>;
interrupts = <2 25>;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 3/8] ARM: bcm2835: Add DT for the firmware clocks driver.

2015-07-20 Thread Eric Anholt
Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---

v2: Rename our compat string to mention bcm2835, and make our firmware
phandle be under a vendor-namespaced property.

 arch/arm/boot/dts/bcm2835-rpi.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index ab5474e..7cc47fb 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -20,6 +20,12 @@
compatible = "raspberrypi,bcm2835-firmware";
mboxes = <&mailbox>;
};
+
+   firmware_clocks: firmware-clocks {
+   compatible = "raspberrypi,bcm2835-firmware-clocks";
+   #clock-cells = <1>;
+   raspberrypi,firmware = <&firmware>;
+   };
};
 };
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 4/8] ARM: bcm2835: Drop never-used clock-frequency property of uart0.

2015-07-20 Thread Eric Anholt
This appears to have been copy-and-paste from another serial driver's
DT.  The driver has never used this value -- instead, the pl011 driver
is getting the fixed 20201000.uart clock from clk-bcm2835.c.

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---
 arch/arm/boot/dts/bcm2835.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..32f5830 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -96,7 +96,6 @@
compatible = "brcm,bcm2835-pl011", "arm,pl011", 
"arm,primecell";
reg = <0x7e201000 0x1000>;
interrupts = <2 25>;
-   clock-frequency = <300>;
arm,primecell-periphid = <0x00241011>;
};
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 7/8] ARM: bcm2835: Tie SPI clock to the core clock rate.

2015-07-20 Thread Eric Anholt
We were previously using a fixed clock declared in the 2835 DT, but
it's actually the core clock, and it might not be the same if you had
adjusted it using the firmware's config.txt.

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 9549eb8..0a32123 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -69,3 +69,7 @@
 <&firmware_clocks RPI_CLOCK_CORE>;
clock-names = "uartclk", "apb_pclk";
 };
+
+&spi {
+   clocks = <&firmware_clocks RPI_CLOCK_CORE>;
+};
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/8] clk: Add a Raspberry Pi-specific clock driver.

2015-07-20 Thread Eric Anholt
Unfortunately, the clock manager's registers are not accessible by the
ARM, so we have to request that the firmware modify our clocks for us.

This driver only registers the clocks at the point they are requested
by a client driver.  This is partially to support returning
-EPROBE_DEFER when the firmware driver isn't supported yet, but it
also avoids issues with disabling "unused" clocks due to them not yet
being connected to their consumers in the DT.

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---

v2: Declare the mutex static (from review by Baruch Siach), merge
description and copyright comments.

v3: Update for new rpi firmware API.  Update the compatible string.
Make the firmware handle be under a vendor-namespaced property.
Make the DT indices match the firmware clock IDs.  Move the driver
under the firmware driver's Kconfig, since it requires it.  Move a
container_of() from 2 callers into the callee.

v4: Update commit message to mention subsystem.  Add #defines for a
couple of bitfield checks, and use the bitfield check for
rpi_clk_is_on().  Return an error when appropriate in
rpi_clk_is_on(), and return specific rpi_firmware_property()
errors in other places when we were only returning -EINVAL.  Add
some comment text describing how return values work from the
firmware.

 drivers/clk/Makefile  |   1 +
 drivers/clk/clk-raspberrypi.c | 259 ++
 2 files changed, 260 insertions(+)
 create mode 100644 drivers/clk/clk-raspberrypi.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c4cf075..ad0a4a5 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_ASM9260)+= clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)   += clk-axm5516.o
 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += clk-raspberrypi.o
 obj-$(CONFIG_COMMON_CLK_CDCE706)   += clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)   += clk-efm32gg.o
diff --git a/drivers/clk/clk-raspberrypi.c b/drivers/clk/clk-raspberrypi.c
new file mode 100644
index 000..ae35804
--- /dev/null
+++ b/drivers/clk/clk-raspberrypi.c
@@ -0,0 +1,259 @@
+/*
+ * Implements a clock provider for the clocks controlled by the
+ * firmware on Raspberry Pi.
+ *
+ * These clocks are controlled by the CLOCKMAN peripheral in the
+ * hardware, but the ARM doesn't have access to the registers for
+ * them.  As a result, we have to call into the firmware to get it to
+ * enable, disable, and set their frequencies.
+ *
+ * We don't have an interface for getting the set of frequencies
+ * available from the hardware.  We can request a min/max, but other
+ * than that we have to request a frequency and take what it gives us.
+ *
+ * Copyright ?? 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+
+#define RPI_FIRMWARE_CLOCK_STATE_ENABLED   (1 << 0)
+#define RPI_FIRMWARE_CLOCK_STATE_ERROR (1 << 1)
+#define RPI_FIRMWARE_SET_CLOCK_RATE_ERROR  0
+
+struct rpi_firmware_clock {
+   /* Clock definitions in our static struct. */
+   const char *name;
+
+   /* The rest are filled in at init time. */
+   struct clk_hw hw;
+   struct device *dev;
+   struct rpi_firmware *firmware;
+};
+
+static struct rpi_firmware_clock rpi_clocks[] = {
+   [RPI_CLOCK_EMMC] = { "emmc" },
+   [RPI_CLOCK_UART0] = { "uart0" },
+   [RPI_CLOCK_ARM] = { "arm" },
+   [RPI_CLOCK_CORE] = { "core" },
+   [RPI_CLOCK_V3D] = { "v3d" },
+   [RPI_CLOCK_H264] = { "h264" },
+   [RPI_CLOCK_ISP] = { "isp" },
+   [RPI_CLOCK_SDRAM] = { "sdram" },
+   [RPI_CLOCK_PIXEL] = { "pixel" },
+   [RPI_CLOCK_PWM] = { "pwm" },
+};
+
+static int rpi_clock_id(struct rpi_firmware_clock *rpi_clk)
+{
+   return rpi_clk - rpi_clocks;
+}
+
+static int rpi_clk_is_on(struct clk_hw *hw)
+{
+   struct rpi_firmware_clock *rpi_clk =
+   container_of(hw, struct rpi_firmware_clock, hw);
+   u32 packet[2];
+   int ret;
+
+   packet[0] = rpi_clock_id(rpi_clk);
+   packet[1] = 0;
+   ret = rpi_firmware_property(rpi_clk->firmware,
+   RPI_FIRMWARE_GET_CLOCK_STATE,
+   &packet, sizeof(packet));
+   /* The second packet field has the new clock state returned in
+* the low bit, or an error flag in the second bit.
+*/
+   if (ret || (packe

[PATCH v4 5/8] clk: bcm2835: Drop the fixed sys_pclk.

2015-07-20 Thread Eric Anholt
Nothing uses it, and I can't find any evidence that anything ever has.
Its role is now filled by the core clock in the firmware driver.

Signed-off-by: Eric Anholt 
Acked-by: Stephen Warren 
---
 drivers/clk/clk-bcm2835.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
index 6b950ca..dd295e4 100644
--- a/drivers/clk/clk-bcm2835.c
+++ b/drivers/clk/clk-bcm2835.c
@@ -32,11 +32,6 @@ void __init bcm2835_init_clocks(void)
struct clk *clk;
int ret;
 
-   clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
-   25000);
-   if (IS_ERR(clk))
-   pr_err("sys_pclk not registered\n");
-
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
12600);
if (IS_ERR(clk))
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 8/8] ARM: bcm2835: Use the firmware on rpi to get the EMMC clock.

2015-07-20 Thread Eric Anholt
This updates the MMC frequency from 100Mhz to 250Mhz.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 0a32123..5d370cb 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -62,6 +62,7 @@
 &sdhci {
status = "okay";
bus-width = <4>;
+   clocks = <&firmware_clocks RPI_CLOCK_EMMC>;
 };
 
 &uart0 {
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/3] clk: bcm2835: Add bindings for the auxiliary peripheral clock gates.

2016-01-02 Thread Eric Anholt
Michael Turquette  writes:

> Hi Arnd,
>
> Quoting Arnd Bergmann (2015-12-30 01:29:02)
>> It's also ok to merge the header file and binding with either the dts file
>> changes or the driver and then do the other part the following release.
>> 
>> In the past, we've worked around the issue by merging the driver through
>> arm-soc, or by merging the dts changes through a driver tree, with the
>> appropriate Acks in each case. Both of those approaches work of course,
>> but the former always feels awkward to me as we are not using the right
>> maintainer path, and the latter approach tends to cause merge conflicts,
>> especially when multiple headers for different subsystems get added or
>> the dts files are added at the same time.
>> 
>> Having a shared branch for the header file is another way to do it, and
>> we can do that in some cases, but I'd prefer not to make it the default.
>
> Well, I'm thinking that an immutable branch isn't such a bad idea given
> that both you and Rob are OK with subsystems merging headers and binding
> descriptions.
>
> A while back Stephen Boyd and I started to use topic branches for every
> driver, all based on -rc1 and merging those into clk-next. This makes it
> trivial for us to push a shareable branch with minimal dependencies.
>
> So at least for the clk tree, how do you feel about us merging driver +
> header + binding description and then sharing our topic branch as-needed
> with arm-soc? We could even push our topic branches by default to cut
> down on coordinating over email back-and-forth.
>
> As an example, patch #1 from the Hi3519 series[0] includes the clk
> driver, binding description and a shared header. Any objection to me
> taking that patch as-is, based on -rc1, and pushing out that topic
> branch as clk-hi3519 to the clk git tree with the expectation that
> you'll just merge that if you need to?
>
> You can let me know if you've pulled it in, and then I won't rebase
> without consulting with the arm-soc folks first.
>
> Does this workflow agreement Solve All the Problems?
>
> (Note that the patch I referenced is still under review so the branch
> name I mentioned above doesn't exist yet. It is just an example)

For what it's worth, this is a nice workflow for me as a driver
developer.  I have a couple of .dts patches that ended up waiting this
cycle because I didn't have the shareable branches necessary.


signature.asc
Description: PGP signature


Re: [PATCH v5 01/13] mmc: sdhci-bcm2835: use sdhci_pltfm_init for private allocation

2016-02-16 Thread Eric Anholt
Jisheng Zhang  writes:

> Commit 0e748234293f ("mmc: sdhci: Add size for caller in init+register")
> allows users of sdhci_pltfm to allocate private space in calls to
> sdhci_pltfm_init+sdhci_pltfm_register. This patch migrates sdhci-bcm2835
> to this allocation.
>
> Signed-off-by: Jisheng Zhang 
> Acked-by: Arnd Bergmann 
> Acked-by: Adrian Hunter 

Acked-by: Eric Anholt 


signature.asc
Description: PGP signature


Re: [PATCH 2/3] drm/vc4: Enable runtime PM.

2016-02-16 Thread Eric Anholt
Eric Anholt  writes:
> +#ifdef CONFIG_PM_SLEEP
> +static int vc4_v3d_runtime_suspend(struct device *dev)
> +{
> + struct vc4_v3d *v3d = dev_get_drvdata(dev);
> + struct vc4_dev *vc4 = v3d->vc4;
> +
> + vc4_irq_uninstall(vc4->dev);
> +
> + return 0;
> +}
> +
> +static int vc4_v3d_runtime_resume(struct device *dev)
> +{
> + struct vc4_v3d *v3d = dev_get_drvdata(dev);
> + struct vc4_dev *vc4 = v3d->vc4;
> +
> + vc4_v3d_init_hw(vc4->dev);
> + vc4_irq_postinstall(vc4->dev);
> +
> + return 0;
> +}
> +#endif

kbuild test robot caught that this #ifdef should have been CONFIG_PM,
not CONFIG_PM_SLEEP.  Fixed in v2.


signature.asc
Description: PGP signature


[PATCH 3/6] drm/vc4: Add another reg to HDMI debug dumping.

2016-02-16 Thread Eric Anholt
This is also involved in the HDMI setup sequence so it's nice to see
it.

Signed-off-by: Eric Anholt 
---

This patch and the next one I'd target for -next, since they aren't
functional fixes.

 drivers/gpu/drm/vc4/vc4_hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index d189906..b4e7b8a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -95,6 +95,7 @@ static const struct {
HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
HDMI_REG(VC4_HDMI_HOTPLUG_INT),
HDMI_REG(VC4_HDMI_HOTPLUG),
+   HDMI_REG(VC4_HDMI_RAM_PACKET_CONFIG),
HDMI_REG(VC4_HDMI_HORZA),
HDMI_REG(VC4_HDMI_HORZB),
HDMI_REG(VC4_HDMI_FIFO_CTL),
-- 
2.7.0



[PATCH 4/6] drm/vc4: Fix the name of the VSYNCD_EVEN register.

2016-02-16 Thread Eric Anholt
It's used for delaying vsync in interlaced mode.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
 drivers/gpu/drm/vc4/vc4_regs.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index bb74cb9..5daa824 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -88,7 +88,7 @@ static const struct {
 } crtc_regs[] = {
CRTC_REG(PV_CONTROL),
CRTC_REG(PV_V_CONTROL),
-   CRTC_REG(PV_VSYNCD),
+   CRTC_REG(PV_VSYNCD_EVEN),
CRTC_REG(PV_HORZA),
CRTC_REG(PV_HORZB),
CRTC_REG(PV_VERTA),
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 31042a4..58d4cb3 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -187,7 +187,7 @@
 # define PV_VCONTROL_CONTINUOUSBIT(1)
 # define PV_VCONTROL_VIDEN BIT(0)
 
-#define PV_VSYNCD  0x08
+#define PV_VSYNCD_EVEN 0x08
 
 #define PV_HORZA   0x0c
 # define PV_HORZA_HBP_MASK VC4_MASK(31, 16)
-- 
2.7.0



drm/vc4: Modesetting fixes

2016-02-16 Thread Eric Anholt
This series fixes the highest priority problems reported from the
driver getting enabled in Raspbian: modesetting on HDMI was broken if
you weren't at the same resolution that the firmware had set up, or if
the firmware hadn't set up HDMI at all.



[PATCH 2/6] drm/vc4: Bring HDMI up from power off if necessary.

2016-02-16 Thread Eric Anholt
If the firmware hadn't brought up HDMI for us, we need to do its
power-on reset sequence (reset HD and and clear its STANDBY bits,
reset HDMI, and leave the PHY disabled).

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 29 -
 drivers/gpu/drm/vc4/vc4_regs.h |  2 ++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c49cb44..d189906 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -497,6 +497,16 @@ static int vc4_hdmi_bind(struct device *dev, struct device 
*master, void *data)
goto err_put_i2c;
}
 
+   /* This is the rate that is set by the firmware.  The number
+* needs to be a bit higher than the pixel clock rate
+* (generally 148.5Mhz).
+*/
+   ret = clk_set_rate(hdmi->hsm_clock, 163682864);
+   if (ret) {
+   DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
+   goto err_unprepare_pix;
+   }
+
ret = clk_prepare_enable(hdmi->hsm_clock);
if (ret) {
DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
@@ -518,7 +528,24 @@ static int vc4_hdmi_bind(struct device *dev, struct device 
*master, void *data)
vc4->hdmi = hdmi;
 
/* HDMI core must be enabled. */
-   WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
+   if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
+   HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
+   udelay(1);
+   HD_WRITE(VC4_HD_M_CTL, 0);
+
+   HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
+
+   HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
+  VC4_HDMI_SW_RESET_HDMI |
+  VC4_HDMI_SW_RESET_FORMAT_DETECT);
+
+   HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 0);
+
+   /* PHY should be in reset, like
+* vc4_hdmi_encoder_disable() does.
+*/
+   HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+   }
 
drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
 DRM_MODE_ENCODER_TMDS, NULL);
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 25df20e..31042a4 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -456,6 +456,8 @@
 #define VC4_HDMI_TX_PHY_RESET_CTL  0x2c0
 
 #define VC4_HD_M_CTL   0x00c
+# define VC4_HD_M_REGISTER_FILE_STANDBY(3 << 6)
+# define VC4_HD_M_RAM_STANDBY  (3 << 4)
 # define VC4_HD_M_SW_RST   BIT(2)
 # define VC4_HD_M_ENABLE   BIT(0)
 
-- 
2.7.0



[PATCH 6/6] drm/vc4: Initialize scaler DISPBKGND on modeset.

2016-02-16 Thread Eric Anholt
We weren't updating the interlaced bit, so we'd scan out incorrectly
if the firmware had brought up the TV encoder and we were switching to
HDMI.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c |  6 ++
 drivers/gpu/drm/vc4/vc4_regs.h | 14 ++
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 89562904..66499e3 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -188,6 +188,8 @@ static int vc4_get_clock_select(struct drm_crtc *crtc)
 
 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_crtc_state *state = crtc->state;
struct drm_display_mode *mode = &state->adjusted_mode;
@@ -256,6 +258,10 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
   PV_CONTROL_FIFO_CLR |
   PV_CONTROL_EN);
 
+   HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
+ SCALER_DISPBKGND_AUTOHS |
+ (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
+
if (debug_dump_regs) {
DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
vc4_crtc_dump_regs(vc4_crtc);
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 58d4cb3..bf42a8e 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -350,6 +350,17 @@
 # define SCALER_DISPCTRLX_HEIGHT_SHIFT 0
 
 #define SCALER_DISPBKGND0   0x0044
+# define SCALER_DISPBKGND_AUTOHS   BIT(31)
+# define SCALER_DISPBKGND_INTERLACEBIT(30)
+# define SCALER_DISPBKGND_GAMMABIT(29)
+# define SCALER_DISPBKGND_TESTMODE_MASKVC4_MASK(28, 25)
+# define SCALER_DISPBKGND_TESTMODE_SHIFT   25
+/* Enables filling the scaler line with the RGB value in the low 24
+ * bits before compositing.  Costs cycles, so should be skipped if
+ * opaque display planes will cover everything.
+ */
+# define SCALER_DISPBKGND_FILL BIT(24)
+
 #define SCALER_DISPSTAT00x0048
 #define SCALER_DISPBASE00x004c
 # define SCALER_DISPSTATX_MODE_MASKVC4_MASK(31, 30)
@@ -362,6 +373,9 @@
 # define SCALER_DISPSTATX_EMPTYBIT(28)
 #define SCALER_DISPCTRL10x0050
 #define SCALER_DISPBKGND1   0x0054
+#define SCALER_DISPBKGNDX(x)   (SCALER_DISPBKGND0 +\
+(x) * (SCALER_DISPBKGND1 - \
+   SCALER_DISPBKGND0))
 #define SCALER_DISPSTAT10x0058
 #define SCALER_DISPSTATX(x)(SCALER_DISPSTAT0 +\
 (x) * (SCALER_DISPSTAT1 - \
-- 
2.7.0



[PATCH 5/6] drm/vc4: Fix setting of vertical timings in the CRTC.

2016-02-16 Thread Eric Anholt
It looks like when I went to add the interlaced bits, I just took the
existing PV_VERT* block and indented it, instead of copy and pasting
it first.  Without this, changing resolution never worked.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 5daa824..89562904 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -217,6 +217,16 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 PV_HORZB_HFP) |
   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
 
+   CRTC_WRITE(PV_VERTA,
+  VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
+PV_VERTA_VBP) |
+  VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
+PV_VERTA_VSYNC));
+   CRTC_WRITE(PV_VERTB,
+  VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
+PV_VERTB_VFP) |
+  VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
+
if (interlace) {
CRTC_WRITE(PV_VERTA_EVEN,
   VC4_SET_FIELD(mode->vtotal - mode->vsync_end - 1,
-- 
2.7.0



[PATCH 1/6] drm/vc4: Fix a framebuffer reference leak on async flip interrupt.

2016-02-16 Thread Eric Anholt
We'd need X to queue up an async pageflip while another is
outstanding, and then take a SIGIO.  I think X actually avoids sending
out the next pageflip while one's already queued, but I'm not sure.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 68227cc..bb74cb9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -527,6 +527,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
/* Make sure all other async modesetes have landed. */
ret = down_interruptible(&vc4->async_modeset);
if (ret) {
+   drm_framebuffer_unreference(fb);
kfree(flip_state);
return ret;
}
-- 
2.7.0



[GIT PULL 2/2] bcm2835 changes to DT for 4.6

2016-02-17 Thread Eric Anholt
The following changes since commit 92e963f50fc74041b5e9e744c330dca48e04f08d:

  Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)

are available in the git repository at:

  g...@github.com:anholt/linux.git bcm2835-dt-next-2016-02-17

for you to fetch changes up to 1305141d1a7254b53b35303ee84f4c4948007bd0:

  ARM: bcm2835: add bcm2835-aux-uart support to DT (2016-02-17 11:01:00 -0800)


This pull request covers mostly DT changes that didn't make it into
4.5 because required header files went through other trees, plus the
AUX uart support this time around.


Alexander Aring (1):
  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT.

Lubomir Rintel (1):
  ARM: bcm2835: dt: Add Raspberry Pi Model A

Martin Sperl (3):
  ARM: bcm2835: add the auxiliary spi1 and spi2 to the device tree
  ARM: bcm2835: follow dt uart node-naming convention
  ARM: bcm2835: add bcm2835-aux-uart support to DT

Remi Pommarel (1):
  ARM: bcm2835: Add PWM clock support to the device tree

 arch/arm/boot/dts/Makefile  |  1 +
 arch/arm/boot/dts/bcm2835-rpi-a.dts | 24 +
 arch/arm/boot/dts/bcm2835-rpi.dtsi  | 16 ++
 arch/arm/boot/dts/bcm283x.dtsi  | 43 +++--
 4 files changed, 82 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2835-rpi-a.dts


Re: [GIT PULL] bcm2835 DT changes for 4.6

2016-02-17 Thread Eric Anholt
Florian Fainelli  writes:

> On 12/02/2016 16:53, Eric Anholt wrote:
>> Florian Fainelli  writes:
>> 
>>> On 10/02/2016 10:51, Eric Anholt wrote:
>>>> Martin Sperl  writes:
>>>>
>>>>>> On 09.02.2016, at 01:32, Eric Anholt  wrote:
>>>>>>
>>>>>> Hi Florian.  Here's the first set of patches for bcm2835 for 4.6.
>>>>>> We've got more DT patches that are going to happen for new boards,
>>>>>> too, but they're still getting polished.
>>>>>>
>>>>>> The following changes since commit 
>>>>>> 92e963f50fc74041b5e9e744c330dca48e04f08d:
>>>>>>
>>>>>>  Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)
>>>>>>
>>>>>> are available in the git repository at:
>>>>>>
>>>>>>  g...@github.com:anholt/linux.git tags/bcm2835-dt-next-2016-02-04
>>>>>>
>>>>>> for you to fetch changes up to 5ec6f2cd8ec4bcd38ba199ea8711a5ec906d85e7:
>>>>>>
>>>>>>  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT. 
>>>>>> (2016-02-02 20:02:45 -0800)
>>>>>>
>>>>>> 
>>>>>> This pull request covers mostly DT changes that didn't make it into
>>>>>> 4.5 because required header files went through other trees.
>>>>>>
>>>>>> 
>>>>>> Alexander Aring (1):
>>>>>>  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT.
>>>>>>
>>>>>> Lubomir Rintel (1):
>>>>>>  ARM: bcm2835: dt: Add Raspberry Pi Model A
>>>>>>
>>>>>> Martin Sperl (2):
>>>>>>  ARM: bcm2835: add the auxiliary spi1 and spi2 to the device tree
>>>>>>  ARM: bcm2835: follow dt uart node-naming convention
>>>>>
>>>>> Do you want me to resend a rebased version of:
>>>>>  ARM: bcm2835: add bcm2835-aux-uart support to default DT
>>>>>
>>>>> The corresponding driver has been added to tty/tty-next.
>>>>
>>>> It hadn't landed last time I checked.  A rebased version that you've
>>>> tested would be great!
>>>
>>> OK, please submit this in the next week or so at most, so we can get
>>> this pull request merged, thanks!
>>>
>>> Eric, do you have other changes outside of Device Tree?
>> 
>> We've got bcm2835_defconfig changes that I need to test and tag.
>
> Ok, so that one needs to be a pull request.
>
>> 
>> There are also the multi_v7_defconfig updates to enable bcm2835.  Would
>> I be pulling those, or someone above me?
>
> This one could too, or it could be an individual patch that the arm-soc
> maintainers take directly, either way is fine AFAIR.

All right, I included it in my pull request.  Thanks!


signature.asc
Description: PGP signature


[GIT PULL 1/2] bcm2835 changes to defconfigs for 4.6

2016-02-17 Thread Eric Anholt
The following changes since commit 92e963f50fc74041b5e9e744c330dca48e04f08d:

  Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)

are available in the git repository at:

  g...@github.com:anholt/linux.git bcm2835-defconfig-next-2016-02-17

for you to fetch changes up to 0a05d3b71ada526ef93019fb3fbd6a95561a8a5f:

  ARM: multi_v7_defconfig: Enable BCM283x (2016-02-17 11:18:05 -0800)


This pull request brings in defconfig changes to enable bcm2836 in the
2835 and multi_v7 defconfigs.


Daniel Stone (1):
  ARM: multi_v7_defconfig: Enable BCM283x

Stefan Wahren (2):
  ARM: bcm2835_defconfig: Enable RPi firmware driver
  ARM: bcm2835_defconfig: Enable RPi power domain driver

Stephen Warren (3):
  ARM: bcm2835_defconfig: rebuild on next-20160205
  ARM: bcm2835_defconfig: disable DEBUG_LL
  ARM: bcm2835_defconfig: enable ARMv7 support

 arch/arm/configs/bcm2835_defconfig  | 11 +--
 arch/arm/configs/multi_v7_defconfig | 12 
 2 files changed, 17 insertions(+), 6 deletions(-)


[GIT PULL] drm/vc4: changes for drm-next.

2016-02-17 Thread Eric Anholt
These changes have been on the list for just under 2 weeks
(and sitting under a lot of the other development I've been doing), so
I think they're ready to go for -next.  They're also a big deal for
getting multiple encoders going, which I'm hoping will happen soon.

The following changes since commit 5443ce86fa37e7d3cc63d2067d05e3388fdeec17:

  drm: virtio-gpu: set atomic flag (2016-02-11 08:56:23 +1000)

are available in the git repository at:

  g...@github.com:anholt/linux.git tags/drm-vc4-next-2016-02-17

for you to fetch changes up to fc04023fafecf19ebd09278d8d67dc5ed1f68b46:

  drm/vc4: Add support for YUV planes. (2016-02-16 11:24:08 -0800)


This pull request brings in overlay plane support for vc4.

----
Eric Anholt (10):
  drm/vc4: Improve comments on vc4_plane_state members.
  drm/vc4: Add missing __iomem annotation to hw_dlist.
  drm/vc4: Move the plane clipping/scaling setup to a separate function.
  drm/vc4: Add a proper short-circut path for legacy cursor updates.
  drm/vc4: Make the CRTCs cooperate on allocating display lists.
  drm/vc4: Add more display planes to each CRTC.
  drm/vc4: Fix which value is being used for source image size.
  drm/vc4: Add support for scaling of display planes.
  drm/vc4: Add support a few more RGB display plane formats.
  drm/vc4: Add support for YUV planes.

 drivers/gpu/drm/vc4/vc4_crtc.c  | 171 +++-
 drivers/gpu/drm/vc4/vc4_drv.h   |  12 +-
 drivers/gpu/drm/vc4/vc4_hvs.c   |  97 +++
 drivers/gpu/drm/vc4/vc4_kms.c   |   9 +
 drivers/gpu/drm/vc4/vc4_plane.c | 603 
 drivers/gpu/drm/vc4/vc4_regs.h  | 102 ++-
 6 files changed, 872 insertions(+), 122 deletions(-)


[GIT PULL] drm/vc4: changes for drm-fixes

2016-02-17 Thread Eric Anholt
These changes have been on the list for over a week without comment,
so I think it might be an appropriate time to pull (without an active
development community, getting review will probably be hard).  I'm
also curious when your window for taking fixes would close -- the
modesetting series I sent yesterday covers what most users have been
running into.

The following changes since commit 388f7b1d6e8ca06762e2454d28d6c3c55ad0fe95:

  Linux 4.5-rc3 (2016-02-07 15:38:30 -0800)

are available in the git repository at:

  g...@github.com:anholt/linux.git tags/drm-vc4-fixes-2016-02-17

for you to fetch changes up to 36cb6253f9383fd9a59ee7b8458c6232ef48577c:

  drm/vc4: Use runtime PM to power cycle the device when the GPU hangs. 
(2016-02-16 12:21:01 -0800)


This pull request fixes GPU reset (which was disabled shortly after
V3D integration due to build breakage) and waits for idle in the
presence of signals (which X likes to do a lot).


Eric Anholt (8):
  drm/vc4: Validate that WAIT_BO padding is cleared.
  drm/vc4: Fix the clear color for the first tile rendered.
  drm/vc4: Return an ERR_PTR from BO creation instead of NULL.
  drm/vc4: Fix -ERESTARTSYS error return from BO waits.
  drm/vc4: Drop error message on seqno wait timeouts.
  drm/vc4: Fix spurious GPU resets due to BO reuse.
  drm/vc4: Enable runtime PM.
  drm/vc4: Use runtime PM to power cycle the device when the GPU hangs.

 drivers/gpu/drm/vc4/vc4_bo.c| 16 -
 drivers/gpu/drm/vc4/vc4_drv.h   | 13 ++--
 drivers/gpu/drm/vc4/vc4_gem.c   | 65 -
 drivers/gpu/drm/vc4/vc4_irq.c   |  2 +-
 drivers/gpu/drm/vc4/vc4_render_cl.c | 22 ++---
 drivers/gpu/drm/vc4/vc4_v3d.c   | 48 ---
 drivers/gpu/drm/vc4/vc4_validate.c  |  4 +--
 7 files changed, 118 insertions(+), 52 deletions(-)


[PATCH] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock

2016-02-18 Thread Eric Anholt
Fixes dmesg spam when we just need to wait a moment for the clock
driver to probe.

Signed-off-by: Eric Anholt 
---
 drivers/i2c/busses/i2c-bcm2835.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index 818b051..d4f3239 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -253,7 +253,8 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 
i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c_dev->clk)) {
-   dev_err(&pdev->dev, "Could not get clock\n");
+   if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER)
+   dev_err(&pdev->dev, "Could not get clock\n");
return PTR_ERR(i2c_dev->clk);
}
 
-- 
2.7.0



[PATCH 3/3] drm/vc4: Use runtime PM to power cycle the device when the GPU hangs.

2016-02-08 Thread Eric Anholt
This gets us functional GPU reset again, like we had until a refactor
at merge time.  Tested with a little patch to stuff in a broken binner
job every 100 frames.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_drv.h |  6 +-
 drivers/gpu/drm/vc4/vc4_gem.c | 26 +-
 drivers/gpu/drm/vc4/vc4_v3d.c | 12 
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index b65e785..83db0b7 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -91,6 +91,11 @@ struct vc4_dev {
struct vc4_bo *overflow_mem;
struct work_struct overflow_mem_work;
 
+   int power_refcount;
+
+   /* Mutex controlling the power refcount. */
+   struct mutex power_lock;
+
struct {
struct timer_list timer;
struct work_struct reset_work;
@@ -449,7 +454,6 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
 extern struct platform_driver vc4_v3d_driver;
 int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
 int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
-int vc4_v3d_set_power(struct vc4_dev *vc4, bool on);
 
 /* vc4_validate.c */
 int
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 440ad03..5df46d6 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -229,8 +229,16 @@ vc4_reset(struct drm_device *dev)
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
DRM_INFO("Resetting GPU.\n");
-   vc4_v3d_set_power(vc4, false);
-   vc4_v3d_set_power(vc4, true);
+
+   mutex_lock(&vc4->power_lock);
+   if (vc4->power_refcount) {
+   /* Power the device off and back on the by dropping the
+* reference on runtime PM.
+*/
+   pm_runtime_put_sync_suspend(&vc4->v3d->pdev->dev);
+   pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+   }
+   mutex_unlock(&vc4->power_lock);
 
vc4_irq_reset(dev);
 
@@ -646,7 +654,10 @@ vc4_complete_exec(struct drm_device *dev, struct 
vc4_exec_info *exec)
}
mutex_unlock(&dev->struct_mutex);
 
-   pm_runtime_put(&vc4->v3d->pdev->dev);
+   mutex_lock(&vc4->power_lock);
+   if (--vc4->power_refcount == 0)
+   pm_runtime_put(&vc4->v3d->pdev->dev);
+   mutex_unlock(&vc4->power_lock);
 
kfree(exec);
 }
@@ -785,7 +796,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_submit_cl *args = data;
struct vc4_exec_info *exec;
-   int ret;
+   int ret = 0;
 
if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
DRM_ERROR("Unknown flags: 0x%02x\n", args->flags);
@@ -798,7 +809,10 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
return -ENOMEM;
}
 
-   ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+   mutex_lock(&vc4->power_lock);
+   if (vc4->power_refcount++ == 0)
+   ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+   mutex_unlock(&vc4->power_lock);
if (ret < 0) {
kfree(exec);
return ret;
@@ -858,6 +872,8 @@ vc4_gem_init(struct drm_device *dev)
(unsigned long)dev);
 
INIT_WORK(&vc4->job_done_work, vc4_job_done_work);
+
+   mutex_init(&vc4->power_lock);
 }
 
 void
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 930851f..7b11e21 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -145,18 +145,6 @@ int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused)
 }
 #endif /* CONFIG_DEBUG_FS */
 
-int
-vc4_v3d_set_power(struct vc4_dev *vc4, bool on)
-{
-   /* XXX: This interface is needed for GPU reset, and the way to
-* do it is to turn our power domain off and back on.  We
-* can't just reset from within the driver, because the reset
-* bits are in the power domain's register area, and get set
-* during the poweron process.
-*/
-   return 0;
-}
-
 static void vc4_v3d_init_hw(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
-- 
2.7.0



[PATCH 0/3] vc4: Runtime PM and GPU reset.

2016-02-08 Thread Eric Anholt
Here's a series to re-add GPU reset, which I cut out of the driver in
8483d152db61c5baf5452b844ef65b96ee9a6cfb to deal with a build
regression.  Along the way, I found a bug in hang detection that
seemed to be exacerbated by runtime PM.

My preference would be to get this in -fixes, since without GPU reset
we can end up with a totally wedged desktop (and we do still have some
known GPU hangs).  If not, I'm fine with the first patch to -fixes and
the other two to -next.

Eric Anholt (3):
  drm/vc4: Fix spurious GPU resets due to BO reuse.
  drm/vc4: Enable runtime PM.
  drm/vc4: Use runtime PM to power cycle the device when the GPU hangs.

 drivers/gpu/drm/vc4/vc4_drv.h | 13 +--
 drivers/gpu/drm/vc4/vc4_gem.c | 51 ---
 drivers/gpu/drm/vc4/vc4_v3d.c | 48 ++--
 3 files changed, 90 insertions(+), 22 deletions(-)

-- 
2.7.0



[PATCH 1/3] drm/vc4: Fix spurious GPU resets due to BO reuse.

2016-02-08 Thread Eric Anholt
We were tracking the "where are the head pointers pointing" globally,
so if another job reused the same BOs and execution was at the same
point as last time we checked, we'd stop and trigger a reset even
though the GPU had made progress.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_drv.h |  6 +-
 drivers/gpu/drm/vc4/vc4_gem.c | 19 ++-
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index a7fea77..b4a26fd 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -92,7 +92,6 @@ struct vc4_dev {
struct work_struct overflow_mem_work;
 
struct {
-   uint32_t last_ct0ca, last_ct1ca;
struct timer_list timer;
struct work_struct reset_work;
} hangcheck;
@@ -202,6 +201,11 @@ struct vc4_exec_info {
/* Sequence number for this bin/render job. */
uint64_t seqno;
 
+   /* Last current addresses the hardware was processing when the
+* hangcheck timer checked on us.
+*/
+   uint32_t last_ct0ca, last_ct1ca;
+
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
 
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 48ce30a..1b7adf1 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -257,10 +257,17 @@ vc4_hangcheck_elapsed(unsigned long data)
struct drm_device *dev = (struct drm_device *)data;
struct vc4_dev *vc4 = to_vc4_dev(dev);
uint32_t ct0ca, ct1ca;
+   unsigned long irqflags;
+   struct vc4_exec_info *exec;
+
+   spin_lock_irqsave(&vc4->job_lock, irqflags);
+   exec = vc4_first_job(vc4);
 
/* If idle, we can stop watching for hangs. */
-   if (list_empty(&vc4->job_list))
+   if (!exec) {
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
return;
+   }
 
ct0ca = V3D_READ(V3D_CTNCA(0));
ct1ca = V3D_READ(V3D_CTNCA(1));
@@ -268,14 +275,16 @@ vc4_hangcheck_elapsed(unsigned long data)
/* If we've made any progress in execution, rearm the timer
 * and wait.
 */
-   if (ct0ca != vc4->hangcheck.last_ct0ca ||
-   ct1ca != vc4->hangcheck.last_ct1ca) {
-   vc4->hangcheck.last_ct0ca = ct0ca;
-   vc4->hangcheck.last_ct1ca = ct1ca;
+   if (ct0ca != exec->last_ct0ca || ct1ca != exec->last_ct1ca) {
+   exec->last_ct0ca = ct0ca;
+   exec->last_ct1ca = ct1ca;
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
vc4_queue_hangcheck(dev);
return;
}
 
+   spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
/* We've gone too long with no progress, reset.  This has to
 * be done from a work struct, since resetting can sleep and
 * this timer hook isn't allowed to.
-- 
2.7.0



[PATCH 2/3] drm/vc4: Enable runtime PM.

2016-02-08 Thread Eric Anholt
This may actually get us a feature that the closed driver didn't have:
turning off the GPU in between rendering jobs, while the V3D device is
still opened by the client.

There may be some tuning to be applied here to use autosuspend so that
we don't bounce the device's power so much, but in steady-state
GPU-bound rendering we keep the power on (since we keep multiple jobs
outstanding) and even if we power cycle on every job we can still
manage at least 680 fps.

More importantly, though, runtime PM will allow us to power off the
device to do a GPU reset.

Signed-off-by: Eric Anholt 
---

I'm not 100% sure about the closed driver comparison -- the equivalent
of the kernel side for the closed driver keeps the power on as far as
I can see, but their userspace equivalent may open/close the kernel
more frequenctly than I expect.

 drivers/gpu/drm/vc4/vc4_drv.h |  1 +
 drivers/gpu/drm/vc4/vc4_gem.c | 10 ++
 drivers/gpu/drm/vc4/vc4_v3d.c | 36 
 3 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index b4a26fd..b65e785 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -141,6 +141,7 @@ struct vc4_seqno_cb {
 };
 
 struct vc4_v3d {
+   struct vc4_dev *vc4;
struct platform_device *pdev;
void __iomem *regs;
 };
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 1b7adf1..440ad03 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -23,6 +23,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -626,6 +627,7 @@ fail:
 static void
 vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned i;
 
/* Need the struct lock for drm_gem_object_unreference(). */
@@ -644,6 +646,8 @@ vc4_complete_exec(struct drm_device *dev, struct 
vc4_exec_info *exec)
}
mutex_unlock(&dev->struct_mutex);
 
+   pm_runtime_put(&vc4->v3d->pdev->dev);
+
kfree(exec);
 }
 
@@ -794,6 +798,12 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
return -ENOMEM;
}
 
+   ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+   if (ret < 0) {
+   kfree(exec);
+   return ret;
+   }
+
exec->args = args;
INIT_LIST_HEAD(&exec->unref_list);
 
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 314ff71..930851f 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -17,6 +17,7 @@
  */
 
 #include "linux/component.h"
+#include "linux/pm_runtime.h"
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -167,6 +168,29 @@ static void vc4_v3d_init_hw(struct drm_device *dev)
V3D_WRITE(V3D_VPMBASE, 0);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int vc4_v3d_runtime_suspend(struct device *dev)
+{
+   struct vc4_v3d *v3d = dev_get_drvdata(dev);
+   struct vc4_dev *vc4 = v3d->vc4;
+
+   vc4_irq_uninstall(vc4->dev);
+
+   return 0;
+}
+
+static int vc4_v3d_runtime_resume(struct device *dev)
+{
+   struct vc4_v3d *v3d = dev_get_drvdata(dev);
+   struct vc4_dev *vc4 = v3d->vc4;
+
+   vc4_v3d_init_hw(vc4->dev);
+   vc4_irq_postinstall(vc4->dev);
+
+   return 0;
+}
+#endif
+
 static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
 {
struct platform_device *pdev = to_platform_device(dev);
@@ -179,6 +203,8 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
if (!v3d)
return -ENOMEM;
 
+   dev_set_drvdata(dev, v3d);
+
v3d->pdev = pdev;
 
v3d->regs = vc4_ioremap_regs(pdev, 0);
@@ -186,6 +212,7 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
return PTR_ERR(v3d->regs);
 
vc4->v3d = v3d;
+   v3d->vc4 = vc4;
 
if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
@@ -207,6 +234,8 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
return ret;
}
 
+   pm_runtime_enable(dev);
+
return 0;
 }
 
@@ -216,6 +245,8 @@ static void vc4_v3d_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
 
+   pm_runtime_disable(dev);
+
drm_irq_uninstall(drm);
 
/* Disable the binner's overflow memory address, so the next
@@ -228,6 +259,10 @@ static void vc4_v3d_unbind(struct device *dev, struct 
device *master,
vc4->v3d = NULL;
 }
 
+static const struct dev_pm_ops vc4_v3d_pm_ops = {
+   SET_RUNTIME_PM_OPS(vc4_v3

[GIT PULL] bcm2835 DT changes for 4.6

2016-02-08 Thread Eric Anholt
Hi Florian.  Here's the first set of patches for bcm2835 for 4.6.
We've got more DT patches that are going to happen for new boards,
too, but they're still getting polished.

The following changes since commit 92e963f50fc74041b5e9e744c330dca48e04f08d:

  Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)

are available in the git repository at:

  g...@github.com:anholt/linux.git tags/bcm2835-dt-next-2016-02-04

for you to fetch changes up to 5ec6f2cd8ec4bcd38ba199ea8711a5ec906d85e7:

  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT. (2016-02-02 
20:02:45 -0800)


This pull request covers mostly DT changes that didn't make it into
4.5 because required header files went through other trees.


Alexander Aring (1):
  ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT.

Lubomir Rintel (1):
  ARM: bcm2835: dt: Add Raspberry Pi Model A

Martin Sperl (2):
  ARM: bcm2835: add the auxiliary spi1 and spi2 to the device tree
  ARM: bcm2835: follow dt uart node-naming convention

Remi Pommarel (1):
  ARM: bcm2835: Add PWM clock support to the device tree

 arch/arm/boot/dts/Makefile  |  1 +
 arch/arm/boot/dts/bcm2835-rpi-a.dts | 24 
 arch/arm/boot/dts/bcm2835-rpi.dtsi  | 16 
 arch/arm/boot/dts/bcm283x.dtsi  | 35 +--
 4 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2835-rpi-a.dts


[PATCH 1/5] ARM: bcm2835: Define standard pinctrl groups in the gpio node.

2016-02-26 Thread Eric Anholt
The BCM2835-ARM-Peripherals.pdf documentation specifies what the
function selects do for the pins, and there are a bunch of obvious
groupings to be made.  With these created, we'll be able to replace
bcm2835-rpi.dtsi's main "set all of these pins to alt0" with
references to specific groups we want enabled.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm283x.dtsi | 170 +
 1 file changed, 170 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 8aaf193..e91198e 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -110,6 +110,176 @@
 
interrupt-controller;
#interrupt-cells = <2>;
+
+   /* Defines pin muxing groups according to
+* BCM2835-ARM-Peripherals.pdf page 102.
+*
+* While each pin can have its mux selected
+* for various functions individually, some
+* groups only make sense to switch to a
+* particular function together.
+*/
+   i2c0_gpio0: i2c0_gpio0 {
+   brcm,pins = <0 1>;
+   brcm,function = ;
+   };
+   i2c1_gpio2: i2c1_gpio2 {
+   brcm,pins = <2 3>;
+   brcm,function = ;
+   };
+   gpclk0_gpio4: gpclk0_gpio4 {
+   brcm,pins = <4>;
+   brcm,function = ;
+   };
+   gpclk1_gpio5: gpclk1_gpio5 {
+   brcm,pins = <5>;
+   brcm,function = ;
+   };
+   gpclk2_gpio6: gpclk2_gpio6 {
+   brcm,pins = <6>;
+   brcm,function = ;
+   };
+   spi0_gpio7: spi0_gpio7 {
+   brcm,pins = <7 8 9 10 11>;
+   brcm,function = ;
+   };
+   pwm0_gpio12: pwm0_gpio12 {
+   brcm,pins = <12>;
+   brcm,function = ;
+   };
+   pwm1_gpio13: pwm1_gpio13 {
+   brcm,pins = <13>;
+   brcm,function = ;
+   };
+   uart0_gpio14: uart0_gpio14 {
+   brcm,pins = <14 15>;
+   brcm,function = ;
+   };
+   pcm_gpio18: pcm_gpio18 {
+   brcm,pins = <18 19 20 21>;
+   brcm,function = ;
+   };
+   i2c0_gpio32: i2c0_gpio32 {
+   brcm,pins = <32 34>;
+   brcm,function = ;
+   };
+   spio0_gpio35: spio0_gpio35 {
+   brcm,pins = <35 36 37 38 39>;
+   brcm,function = ;
+   };
+   pwm0_gpio40: pwm0_gpio40 {
+   brcm,pins = <40>;
+   brcm,function = ;
+   };
+   pwm1_gpio41: pwm1_gpio41 {
+   brcm,pins = <41>;
+   brcm,function = ;
+   };
+   gpclk1_gpio42: gpclk1_gpio42 {
+   brcm,pins = <42>;
+   brcm,function = ;
+   };
+   gpclk2_gpio43: gpclk2_gpio43 {
+   brcm,pins = <43>;
+   brcm,function = ;
+   };
+   gpclk1_gpio44: gpclk1_gpio44 {
+   brcm,pins = <44>;
+   brcm,function = ;
+   };
+   pwm1_gpio45: pwm1_gpio45 {
+   brcm,pins = <45>;
+   brcm,function = ;
+   };
+   i2c0_gpio44: i2c0_gpio44 {
+   brcm,pins = <44 45>;
+   brcm,function = ;
+   };
+   pcm_gpio28: pcm_gpio28 {
+   brcm,pins = <28 29 30 31>;
+   brcm,function = ;
+   };
+  

[PATCH 5/5] ARM: bcm2835: Move most RPi default pin groups to their devices.

2016-02-26 Thread Eric Anholt
This way we can get the duplicated pin group definitions out of each
RPi board file, and just leave the i2s variations in them.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-a.dts  | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b.dts  | 12 
 arch/arm/boot/dts/bcm2835-rpi.dtsi   | 20 
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 14 +++---
 7 files changed, 35 insertions(+), 67 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 1db6835..a00cbbe 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -20,15 +20,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio18
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio18>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 25d2114..23e6b6f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -13,15 +13,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio28
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio28>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index d8057b8..029b589 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -20,15 +20,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio18
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio18>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index e7dbff4..da1bc27 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -13,15 +13,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio28
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio28>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index d154049..df275d4 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -12,15 +12,3 @@
};
};
 };
-
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
-};
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index eff27b0..b8efd41 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -31,6 +31,9 @@
 
 &gpio {
pinctrl-names = "default";
+   pinctrl-0 = <&gpclk0_gpio4
+&gpclk1_gpio5
+&gpioout>;
 
gpioout: gpioout {
brcm,pins = <6>;
@@ -39,11 +42,17 @@
 };
 
 &i2c0 {
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c0_gpio0>;
+
status = "okay";
clock-frequency = <10>;
 };
 
 &i2c1 {
+   

[PATCH 2/5] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups.

2016-02-26 Thread Eric Anholt
Since all of these pins were documented, we can use their names to
explain what's going on.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-a.dts  | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b.dts  | 10 +-
 arch/arm/boot/dts/bcm2835-rpi.dtsi   |  5 -
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 17 ++---
 7 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 228614f..0a8b92e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -21,11 +21,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-   /* I2S interface */
-   i2s_alt0: i2s_alt0 {
-   brcm,pins = <18 19 20 21>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio18
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index ddd..d093407 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -14,11 +14,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-   /* I2S interface */
-   i2s_alt2: i2s_alt2 {
-   brcm,pins = <28 29 30 31>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio28
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index ef54050..c26b81d 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -21,11 +21,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-   /* I2S interface */
-   i2s_alt0: i2s_alt0 {
-   brcm,pins = <18 19 20 21>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio18
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 86f1f2f..a5b606e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -14,11 +14,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-   /* I2S interface */
-   i2s_alt2: i2s_alt2 {
-   brcm,pins = <28 29 30 31>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio28
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 4859e9d..97e3c2f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -14,5 +14,13 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &alt3>;
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 76bdbca..141b18c 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -37,11 +37,6 @@
brcm,function = ;
};
 
-   alt0: a

[PATCH 4/5] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost.

2016-02-26 Thread Eric Anholt
This pin group definition comes from downstream.  We don't have a
driver for sdhost integrated yet, but they've been experimenting with
it and it sounds useful to bring over.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm283x.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 70a6814..0bb32cc 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -191,6 +191,10 @@
brcm,pins = <45>;
brcm,function = ;
};
+   sdhost_gpio48: sdhost_gpio48 {
+   brcm,pins = <48 49 50 51 52 53>;
+   brcm,function = ;
+   };
i2c0_gpio44: i2c0_gpio44 {
brcm,pins = <44 45>;
brcm,function = ;
-- 
2.7.0



[PATCH 3/5] ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi.

2016-02-26 Thread Eric Anholt
While it's not documented in the public PDF, it is internally.  This
is a standard pin group for the 283x, not rpi-specific.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-a.dts  | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b.dts  | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi.dtsi   | 5 -
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 4 ++--
 arch/arm/boot/dts/bcm283x.dtsi   | 4 
 8 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 0a8b92e..1db6835 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -29,6 +29,6 @@
 &pcm_gpio18
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index d093407..25d2114 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -22,6 +22,6 @@
 &pcm_gpio28
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index c26b81d..d8057b8 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -29,6 +29,6 @@
 &pcm_gpio18
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index a5b606e..e7dbff4 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -22,6 +22,6 @@
 &pcm_gpio28
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 97e3c2f..d154049 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -21,6 +21,6 @@
 &spi0_gpio7
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 141b18c..eff27b0 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -36,11 +36,6 @@
brcm,pins = <6>;
brcm,function = ;
};
-
-   alt3: alt3 {
-   brcm,pins = <48 49 50 51 52 53>;
-   brcm,function = ;
-   };
 };
 
 &i2c0 {
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts 
b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 52798ca..3e9226f 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -33,6 +33,6 @@
 &pcm_gpio18
 &pwm0_gpio40
 &pwm1_gpio45
-&gpioout
-&alt3>;
+&emmc_gpio48
+&gpioout>;
 };
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index e91198e..70a6814 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -232,6 +232,10 @@
brcm,pins = <32 33>;
brcm,function = ;
};
+   emmc_gpio48: emmc_gpio48 {
+   brcm,pins = <48 49 50 51 52 53>;
+   brcm,function = ;
+   };
spi1_gpio16: spi1_gpio16 {
brcm,pins = <16 17 18 19 20 21>;
brcm,function = ;
-- 
2.7.0



[PATCH 0/5] BCM2835 pinctrl DT rework (resend)

2016-02-26 Thread Eric Anholt
Here's a series for cleaning up the pinctrl groups on BCM2835
(Raspberry Pi).  This was partially inspired by Stefan Wahren's
patches for the EMMC SDHCI controller, but really triggered by needing
to switch pinmuxes to enable the SDHOST SD controller (which gives me
a 60% read speed improvement).  Patches for adding that driver will
follow.

I think this is more or less how pinctrl is expected to be used for a
platform like this.  It certainly cleans up the board files.

This is a resend because only 3 came through last time.  My former
SMTP relay decided to start rejecting half my mails this week.  I've
now swapped systems.

Eric Anholt (5):
  ARM: bcm2835: Define standard pinctrl groups in the gpio node.
  ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups.
  ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi.
  ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost.
  ARM: bcm2835: Move most RPi default pin groups to their devices.

 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts |  11 +-
 arch/arm/boot/dts/bcm2835-rpi-a.dts  |  11 +-
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts |  11 +-
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts |  11 +-
 arch/arm/boot/dts/bcm2835-rpi-b.dts  |   4 -
 arch/arm/boot/dts/bcm2835-rpi.dtsi   |  30 --
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts|  11 +-
 arch/arm/boot/dts/bcm283x.dtsi   | 178 +++
 8 files changed, 213 insertions(+), 54 deletions(-)

-- 
2.7.0



[PATCH 1/4] dt-bindings: Add binding for brcm,bcm2835-sdhost.

2016-02-26 Thread Eric Anholt
This is the other SD controller on the platform, which can be swapped
to the role of SD card host using pin muxing.

Signed-off-by: Eric Anholt 
---
 .../bindings/mmc/brcm,bcm2835-sdhost.txt   | 25 ++
 1 file changed, 25 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt

diff --git a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt 
b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
new file mode 100644
index 000..f55c446
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
@@ -0,0 +1,25 @@
+Broadcom BCM2835 SDHOST controller
+
+This file documents differences between the core properties described
+by mmc.txt and the properties that represent the BCM2835 SDHOST controller.
+
+Required properties:
+- compatible:  Must be "brcm,bcm2835-sdhost"
+- clocks:  The phandle for the clock feeding the SDHOST controller
+
+Optional properties:
+- dmas:DMA channel phandles for read and write
+- dma-names:   DMA channel names for read and write, must be "rx" and "tx"
+ See Documentation/devicetree/bindings/dma/dma.txt for details
+
+Example:
+
+sdhost: sdhost@7e202000 {
+   compatible = "brcm,bcm2835-sdhost";
+   reg = <0x7e202000 0x100>;
+   interrupts = <2 24>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
+   dmas = <&dma 13>,
+  <&dma 13>;
+   dma-names = "tx", "rx";
+};
-- 
2.7.0



[PATCH 0/4] bcm2835 SDHOST controller

2016-02-26 Thread Eric Anholt
Here's a series to enable the SDHOST controller.  It gives us better
performance than our old sdhci-bcm2835.c.  The downstream Raspberry Pi
kernel appears to be using this controller by default at this point.

I've tried to do some testing on it (mounting filesystem,
reading/writing files, speed tests), but I'm not sure what a good
testing regimen for storage drivers would be.

Eric Anholt (4):
  dt-bindings: Add binding for brcm,bcm2835-sdhost.
  mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
  ARM: bcm2835: Include SDHOST in the device tree.
  ARM: bcm2835: Enable SDHOST by default.

 .../bindings/mmc/brcm,bcm2835-sdhost.txt   |   25 +
 arch/arm/boot/dts/bcm2835-rpi.dtsi |   10 +-
 arch/arm/boot/dts/bcm283x.dtsi |8 +
 drivers/mmc/host/Kconfig   |9 +
 drivers/mmc/host/Makefile  |1 +
 drivers/mmc/host/bcm2835-sdhost.c  | 1652 
 6 files changed, 1704 insertions(+), 1 deletion(-)
 create mode 100644 
Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
 create mode 100644 drivers/mmc/host/bcm2835-sdhost.c

-- 
2.7.0



[PATCH 2/4] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.

2016-02-26 Thread Eric Anholt
The 2835 has two SD controllers: The Arasan SDHCI controller that we
currently use, and a custom SD controller.  The custom one runs faster
at 16.7MB/sec reads on PIO (according to hdparm -t on a Pi 2B) instead
of 10.15MB/sec, and up to 18.45MB/sec with DMA enabled.

The code was originally written by Phil Elwell in the downstream
Rasbperry Pi tree, and I did a major cleanup on it (+319, -721 lines
out of the original 2055) for inclusion.

Signed-off-by: Eric Anholt 
---
 drivers/mmc/host/Kconfig  |9 +
 drivers/mmc/host/Makefile |1 +
 drivers/mmc/host/bcm2835-sdhost.c | 1652 +
 3 files changed, 1662 insertions(+)
 create mode 100644 drivers/mmc/host/bcm2835-sdhost.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1526b8a..b991a21 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -778,6 +778,15 @@ config MMC_TOSHIBA_PCI
depends on PCI
help
 
+config MMC_BCM2835_SDHOST
+   tristate "platform support for the BCM2835 SDHOST MMC Controller"
+   depends on ARCH_BCM2835 || COMPILE_TEST
+   help
+ This selects the BCM2835 SDHOST MMC controller. If you have a BCM2835
+ platform with SD or MMC devices, say Y or M here.
+
+ If unsure, say N.
+
 config MMC_MTK
tristate "MediaTek SD/MMC Card Interface support"
depends on HAS_DMA
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 3595f83..b31b994 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_MMC_MOXART)  += moxart-mmc.o
 obj-$(CONFIG_MMC_SUNXI)+= sunxi-mmc.o
 obj-$(CONFIG_MMC_USDHI6ROL0)   += usdhi6rol0.o
 obj-$(CONFIG_MMC_TOSHIBA_PCI)  += toshsd.o
+obj-$(CONFIG_MMC_BCM2835_SDHOST)   += bcm2835-sdhost.o
 
 obj-$(CONFIG_MMC_REALTEK_PCI)  += rtsx_pci_sdmmc.o
 obj-$(CONFIG_MMC_REALTEK_USB)  += rtsx_usb_sdmmc.o
diff --git a/drivers/mmc/host/bcm2835-sdhost.c 
b/drivers/mmc/host/bcm2835-sdhost.c
new file mode 100644
index 000..a84f675
--- /dev/null
+++ b/drivers/mmc/host/bcm2835-sdhost.c
@@ -0,0 +1,1652 @@
+/*
+ * BCM2835 SD host driver.
+ *
+ * Author:  Phil Elwell 
+ *  Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd.
+ *
+ * Based on
+ *  mmc-bcm2835.c by Gellert Weisz
+ * which is, in turn, based on
+ *  sdhci-bcm2708.c by Broadcom
+ *  sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko
+ *  sdhci.c and sdhci-pci.c by Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SDCMD  0x00 /* Command to SD card  - 16 R/W */
+#define SDARG  0x04 /* Argument to SD card - 32 R/W */
+#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */
+#define SDCDIV 0x0c /* Start value for clock divider   - 11 R/W */
+#define SDRSP0 0x10 /* SD card response (31:0) - 32 R   */
+#define SDRSP1 0x14 /* SD card response (63:32)- 32 R   */
+#define SDRSP2 0x18 /* SD card response (95:64)- 32 R   */
+#define SDRSP3 0x1c /* SD card response (127:96)   - 32 R   */
+#define SDHSTS 0x20 /* SD host status  - 11 R   */
+#define SDVDD  0x30 /* SD card power control   -  1 R/W */
+#define SDEDM  0x34 /* Emergency Debug Mode- 13 R/W */
+#define SDHCFG 0x38 /* Host configuration  -  2 R/W */
+#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */
+#define SDDATA 0x40 /* Data to/from SD card- 32 R/W */
+#define SDHBLC 0x50 /* Host block count (SDIO/SDHC)-  9 R/W */
+
+#define SDCMD_NEW_FLAG  0x8000
+#define SDCMD_FAIL_FLAG 0x4000
+#define SDCMD_BUSYWAIT  0x800
+#define SDCMD_NO_RESPONSE   0x400
+#define SDCMD_LONG_RESPONSE 0x200
+#define SDCMD_WRITE_CMD 0x80
+#define SDCMD_READ_CMD  0x40
+#define SDCMD_CMD_MASK  0x3f
+
+#define SDCDIV_MAX_CDIV 0x7ff
+
+#define SDHSTS_BUSY_IRPT0x400
+#define SDHSTS_BLOCK_IRPT   0x200
+#define SDHSTS_SDIO_IRPT0x100
+#define SDHSTS_REW_TIME_OUT 0x80
+#

[PATCH 3/4] ARM: bcm2835: Include SDHOST in the device tree.

2016-02-26 Thread Eric Anholt
It's disabled by default, and will be enabled by a particular board's
DT.  The DMA channels are also currently left out, because our DMA
engine support doesn't yet include slave SG, and there doesn't appear
to be a clean way to include "does slave SG" in the channel
request/config process.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm283x.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 597a78f..7b2721b 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -366,6 +366,14 @@
status = "disabled";
};
 
+   sdhost: sdhost@7e202000 {
+   compatible = "brcm,bcm2835-sdhost";
+   reg = <0x7e202000 0x100>;
+   interrupts = <2 24>;
+   clocks = <&clocks BCM2835_CLOCK_VPU>;
+   status = "disabled";
+   };
+
pwm: pwm@7e20c000 {
compatible = "brcm,bcm2835-pwm";
reg = <0x7e20c000 0x28>;
-- 
2.7.0



[PATCH 4/4] ARM: bcm2835: Enable SDHOST by default.

2016-02-26 Thread Eric Anholt
This improves read speed on my SD card (as reported by hdparm -t) from
10.15MB/sec to 16.70MB/sec.  Once we add slave DMA, we can get to
18.45MB/sec.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index b8efd41..65d3594 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -65,10 +65,18 @@
pinctrl-names = "default";
pinctrl-0 = <&emmc_gpio48>;
 
-   status = "okay";
bus-width = <4>;
 };
 
+&sdhost {
+   pinctrl-names = "default";
+   pinctrl-0 = <&sdhost_gpio48>;
+
+   bus-width = <4>;
+
+   status = "okay";
+};
+
 &pwm {
pinctrl-names = "default";
pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>;
-- 
2.7.0



[PATCH] pinctrl-bcm2835: Fix cut-and-paste error in "pull" parsing

2016-02-29 Thread Eric Anholt
From: Phil Elwell 

The DT bindings for pinctrl-bcm2835 allow both the function and pull
to contain either one entry or one per pin. However, an error in the
DT parsing can cause failures if the number of pulls differs from the
number of functions.

Signed-off-by: Eric Anholt 
Cc: sta...@vger.kernel.org
---

Yes, the s-o-b differs from the author of the commit, but this falls
under part b) of the process.

Phil, any chance you could start putting Signed-off-by lines on your
kernel commits?

 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c 
b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 0f5997c..08b1d93 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -779,7 +779,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev 
*pctldev,
}
if (num_pulls) {
err = of_property_read_u32_index(np, "brcm,pull",
-   (num_funcs > 1) ? i : 0, &pull);
+   (num_pulls > 1) ? i : 0, &pull);
if (err)
goto out;
err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin,
-- 
2.7.0



[PATCH 1/2] drm/vc4: Let gpiolib know that we're OK with sleeping for HPD.

2016-02-29 Thread Eric Anholt
Fixes an error thrown every few seconds when we poll HPD when it's on
a I2C to GPIO expander.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c69c046..709ed57 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -165,7 +165,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
if (vc4->hdmi->hpd_gpio) {
-   if (gpio_get_value(vc4->hdmi->hpd_gpio))
+   if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio))
return connector_status_connected;
else
return connector_status_disconnected;
-- 
2.7.0



[PATCH 0/2] drm/vc4: Fixes for Raspberry Pi 3

2016-02-29 Thread Eric Anholt
These are for fixing the vc4 driver on the Pi 3.  Note that patch 2
will also be necessary for fixing HPD on the Pi2, which we've been
carrying downstream patches to work around until now.

Eric Anholt (2):
  drm/vc4: Let gpiolib know that we're OK with sleeping for HPD.
  drm/vc4: Respect GPIO_ACTIVE_LOW on HDMI HPD if set in the devicetree.

 drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

-- 
2.7.0



[PATCH 2/2] drm/vc4: Respect GPIO_ACTIVE_LOW on HDMI HPD if set in the devicetree.

2016-02-29 Thread Eric Anholt
The original Raspberry Pi had the GPIO active high, but the later
models are active low.  The DT GPIO bindings allow specifying the
active flag, except that it doesn't get propagated to the gpiodesc, so
you have to handle it yourself.

Signed-off-by: Eric Anholt 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 709ed57..dc60485 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -47,6 +47,7 @@ struct vc4_hdmi {
void __iomem *hdmicore_regs;
void __iomem *hd_regs;
int hpd_gpio;
+   bool hpd_active_low;
 
struct clk *pixel_clock;
struct clk *hsm_clock;
@@ -165,7 +166,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
if (vc4->hdmi->hpd_gpio) {
-   if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio))
+   if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
+   vc4->hdmi->hpd_active_low)
return connector_status_connected;
else
return connector_status_disconnected;
@@ -506,11 +508,17 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 * we'll use the HDMI core's register.
 */
if (of_find_property(dev->of_node, "hpd-gpios", &value)) {
-   hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 
0);
+   enum of_gpio_flags hpd_gpio_flags;
+
+   hdmi->hpd_gpio = of_get_named_gpio_flags(dev->of_node,
+"hpd-gpios", 0,
+&hpd_gpio_flags);
if (hdmi->hpd_gpio < 0) {
ret = hdmi->hpd_gpio;
goto err_unprepare_hsm;
}
+
+   hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
}
 
vc4->hdmi = hdmi;
-- 
2.7.0



[PATCH 2/2] clk: bcm2835: Reuse CLK_DIVIDER_MAX_AT_ZERO for recalc_rate()

2016-02-15 Thread Eric Anholt
We were rolling this ourselves, but clk-divider can do it now.

Signed-off-by: Eric Anholt 
---
 drivers/clk/bcm/clk-bcm2835.c | 13 ++---
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 9f4df8f..353e438 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1060,16 +1060,7 @@ static long bcm2835_pll_divider_round_rate(struct clk_hw 
*hw,
 static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw,
  unsigned long parent_rate)
 {
-   struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
-   struct bcm2835_cprman *cprman = divider->cprman;
-   const struct bcm2835_pll_divider_data *data = divider->data;
-   u32 div = cprman_read(cprman, data->a2w_reg);
-
-   div &= (1 << A2W_PLL_DIV_BITS) - 1;
-   if (div == 0)
-   div = 256;
-
-   return parent_rate / div;
+   return clk_divider_ops.recalc_rate(hw, parent_rate);
 }
 
 static void bcm2835_pll_divider_off(struct clk_hw *hw)
@@ -1430,7 +1421,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman 
*cprman,
divider->div.reg = cprman->regs + data->a2w_reg;
divider->div.shift = A2W_PLL_DIV_SHIFT;
divider->div.width = A2W_PLL_DIV_BITS;
-   divider->div.flags = 0;
+   divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO;
divider->div.lock = &cprman->regs_lock;
divider->div.hw.init = &init;
divider->div.table = NULL;
-- 
2.7.0



[PATCH 1/2] clk: bcm2835: Fix setting of PLL divider clock rates

2016-02-15 Thread Eric Anholt
Our dividers weren't being set successfully because CM_PASSWORD wasn't
included in the register write.  It looks easier to just compute the
divider to write ourselves than to update clk-divider for the ability
to OR in some arbitrary bits on write.

Fixes about half of the video modes on my HDMI monitor (everything
except 720x400).

Cc: sta...@vger.kernel.org
Signed-off-by: Eric Anholt 
---
 drivers/clk/bcm/clk-bcm2835.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 015e687..9f4df8f 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1107,13 +1107,15 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw 
*hw,
struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
struct bcm2835_cprman *cprman = divider->cprman;
const struct bcm2835_pll_divider_data *data = divider->data;
-   u32 cm;
-   int ret;
+   u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS;
 
-   ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
-   if (ret)
-   return ret;
+   div = DIV_ROUND_UP_ULL(parent_rate, rate);
+
+   div = min(div, max_div);
+   if (div == max_div)
+   div = 0;
 
+   cprman_write(cprman, data->a2w_reg, div);
cm = cprman_read(cprman, data->cm_reg);
cprman_write(cprman, data->cm_reg, cm | data->load_mask);
cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
-- 
2.7.0



[PATCH 2/5] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups.

2016-02-23 Thread Eric Anholt
Since all of these pins were documented, we can use their names to
explain what's going on.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-a.dts  | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 17 ++---
 arch/arm/boot/dts/bcm2835-rpi-b.dts  | 10 +-
 arch/arm/boot/dts/bcm2835-rpi.dtsi   |  5 -
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 17 ++---
 7 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 228614f..0a8b92e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -21,11 +21,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-   /* I2S interface */
-   i2s_alt0: i2s_alt0 {
-   brcm,pins = <18 19 20 21>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio18
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index ddd..d093407 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -14,11 +14,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-   /* I2S interface */
-   i2s_alt2: i2s_alt2 {
-   brcm,pins = <28 29 30 31>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio28
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index ef54050..c26b81d 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -21,11 +21,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-   /* I2S interface */
-   i2s_alt0: i2s_alt0 {
-   brcm,pins = <18 19 20 21>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio18
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 86f1f2f..a5b606e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -14,11 +14,14 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-   /* I2S interface */
-   i2s_alt2: i2s_alt2 {
-   brcm,pins = <28 29 30 31>;
-   brcm,function = ;
-   };
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pcm_gpio28
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 4859e9d..97e3c2f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -14,5 +14,13 @@
 };
 
 &gpio {
-   pinctrl-0 = <&gpioout &alt0 &alt3>;
+   pinctrl-0 = <&i2c0_gpio0
+&i2c1_gpio2
+&gpclk0_gpio4
+&gpclk1_gpio5
+&spi0_gpio7
+&pwm0_gpio40
+&pwm1_gpio45
+&gpioout
+&alt3>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 76bdbca..141b18c 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -37,11 +37,6 @@
brcm,function = ;
};
 
-   alt0: a

[PATCH 5/5] ARM: bcm2835: Move most RPi default pin groups to their devices.

2016-02-25 Thread Eric Anholt
This way we can get the duplicated pin group definitions out of each
RPi board file, and just leave the i2s variations in them.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-a.dts  | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 14 +++---
 arch/arm/boot/dts/bcm2835-rpi-b.dts  | 12 
 arch/arm/boot/dts/bcm2835-rpi.dtsi   | 20 
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 14 +++---
 7 files changed, 35 insertions(+), 67 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 1db6835..a00cbbe 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -20,15 +20,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio18
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio18>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts 
b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 25d2114..23e6b6f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -13,15 +13,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio28
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio28>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index d8057b8..029b589 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -20,15 +20,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio18
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio18>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index e7dbff4..da1bc27 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -13,15 +13,7 @@
};
 };
 
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pcm_gpio28
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
+&i2s {
+   pinctrl-names = "default";
+   pinctrl-0 = <&pcm_gpio28>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts 
b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index d154049..df275d4 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -12,15 +12,3 @@
};
};
 };
-
-&gpio {
-   pinctrl-0 = <&i2c0_gpio0
-&i2c1_gpio2
-&gpclk0_gpio4
-&gpclk1_gpio5
-&spi0_gpio7
-&pwm0_gpio40
-&pwm1_gpio45
-&emmc_gpio48
-&gpioout>;
-};
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi 
b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index eff27b0..b8efd41 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -31,6 +31,9 @@
 
 &gpio {
pinctrl-names = "default";
+   pinctrl-0 = <&gpclk0_gpio4
+&gpclk1_gpio5
+&gpioout>;
 
gpioout: gpioout {
brcm,pins = <6>;
@@ -39,11 +42,17 @@
 };
 
 &i2c0 {
+   pinctrl-names = "default";
+   pinctrl-0 = <&i2c0_gpio0>;
+
status = "okay";
clock-frequency = <10>;
 };
 
 &i2c1 {
+   

[PATCH 1/5] ARM: bcm2835: Define standard pinctrl groups in the gpio node.

2016-02-25 Thread Eric Anholt
The BCM2835-ARM-Peripherals.pdf documentation specifies what the
function selects do for the pins, and there are a bunch of obvious
groupings to be made.  With these created, we'll be able to replace
bcm2835-rpi.dtsi's main "set all of these pins to alt0" with
references to specific groups we want enabled.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm283x.dtsi | 170 +
 1 file changed, 170 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 8aaf193..e91198e 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -110,6 +110,176 @@
 
interrupt-controller;
#interrupt-cells = <2>;
+
+   /* Defines pin muxing groups according to
+* BCM2835-ARM-Peripherals.pdf page 102.
+*
+* While each pin can have its mux selected
+* for various functions individually, some
+* groups only make sense to switch to a
+* particular function together.
+*/
+   i2c0_gpio0: i2c0_gpio0 {
+   brcm,pins = <0 1>;
+   brcm,function = ;
+   };
+   i2c1_gpio2: i2c1_gpio2 {
+   brcm,pins = <2 3>;
+   brcm,function = ;
+   };
+   gpclk0_gpio4: gpclk0_gpio4 {
+   brcm,pins = <4>;
+   brcm,function = ;
+   };
+   gpclk1_gpio5: gpclk1_gpio5 {
+   brcm,pins = <5>;
+   brcm,function = ;
+   };
+   gpclk2_gpio6: gpclk2_gpio6 {
+   brcm,pins = <6>;
+   brcm,function = ;
+   };
+   spi0_gpio7: spi0_gpio7 {
+   brcm,pins = <7 8 9 10 11>;
+   brcm,function = ;
+   };
+   pwm0_gpio12: pwm0_gpio12 {
+   brcm,pins = <12>;
+   brcm,function = ;
+   };
+   pwm1_gpio13: pwm1_gpio13 {
+   brcm,pins = <13>;
+   brcm,function = ;
+   };
+   uart0_gpio14: uart0_gpio14 {
+   brcm,pins = <14 15>;
+   brcm,function = ;
+   };
+   pcm_gpio18: pcm_gpio18 {
+   brcm,pins = <18 19 20 21>;
+   brcm,function = ;
+   };
+   i2c0_gpio32: i2c0_gpio32 {
+   brcm,pins = <32 34>;
+   brcm,function = ;
+   };
+   spio0_gpio35: spio0_gpio35 {
+   brcm,pins = <35 36 37 38 39>;
+   brcm,function = ;
+   };
+   pwm0_gpio40: pwm0_gpio40 {
+   brcm,pins = <40>;
+   brcm,function = ;
+   };
+   pwm1_gpio41: pwm1_gpio41 {
+   brcm,pins = <41>;
+   brcm,function = ;
+   };
+   gpclk1_gpio42: gpclk1_gpio42 {
+   brcm,pins = <42>;
+   brcm,function = ;
+   };
+   gpclk2_gpio43: gpclk2_gpio43 {
+   brcm,pins = <43>;
+   brcm,function = ;
+   };
+   gpclk1_gpio44: gpclk1_gpio44 {
+   brcm,pins = <44>;
+   brcm,function = ;
+   };
+   pwm1_gpio45: pwm1_gpio45 {
+   brcm,pins = <45>;
+   brcm,function = ;
+   };
+   i2c0_gpio44: i2c0_gpio44 {
+   brcm,pins = <44 45>;
+   brcm,function = ;
+   };
+   pcm_gpio28: pcm_gpio28 {
+   brcm,pins = <28 29 30 31>;
+   brcm,function = ;
+   };
+  

[PATCH 4/5] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost.

2016-02-25 Thread Eric Anholt
This pin group definition comes from downstream.  We don't have a
driver for sdhost integrated yet, but they've been experimenting with
it and it sounds useful to bring over.

Signed-off-by: Eric Anholt 
---
 arch/arm/boot/dts/bcm283x.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 70a6814..0bb32cc 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -191,6 +191,10 @@
brcm,pins = <45>;
brcm,function = ;
};
+   sdhost_gpio48: sdhost_gpio48 {
+   brcm,pins = <48 49 50 51 52 53>;
+   brcm,function = ;
+   };
i2c0_gpio44: i2c0_gpio44 {
brcm,pins = <44 45>;
brcm,function = ;
-- 
2.7.0



Re: [PATCH 1/5] ARM: bcm2835: Define standard pinctrl groups in the gpio node.

2016-02-25 Thread Eric Anholt
Eric Anholt  writes:

> The BCM2835-ARM-Peripherals.pdf documentation specifies what the
> function selects do for the pins, and there are a bunch of obvious
> groupings to be made.  With these created, we'll be able to replace
> bcm2835-rpi.dtsi's main "set all of these pins to alt0" with
> references to specific groups we want enabled.

Sigh.  The host I've been using for relaying SMTP apparently decided
this week that it doesn't like half my mail.

I'll be off fixing this, so for now if anyone wants to look at the
series it's just in my repo:

https://github.com/anholt/linux/tree/bcm2835-dt-gpio


signature.asc
Description: PGP signature


Re: [PATCH 2/3 v8] mailbox: Enable BCM2835 mailbox support

2015-05-07 Thread Eric Anholt
Noralf Trønnes  writes:

> Den 05.05.2015 22:27, skrev Eric Anholt:
>> From: Lubomir Rintel 
>>
>> This mailbox driver provides a single mailbox channel to write 32-bit
>> values to the VPU and get a 32-bit response.  The Raspberry Pi
>> firmware uses this mailbox channel to implement firmware calls, while
>> Roku 2 (despite being derived from the same firmware tree) doesn't.
>>
>> The driver was originally submitted by Lubomir, based on the
>> out-of-tree 2708 mailbox driver.  Eric Anholt fixed it up for
>> upstreaming, with the major functional change being that it now has no
>> notion of multiple channels (since that is a firmware-dependent
>> concept) and instead the raspberrypi-firmware driver will do that
>> bit-twiddling in its own messages.
> ...
>> +static struct platform_driver bcm2835_mbox_driver = {
>> +.driver = {
>> +.name = "bcm2835-mbox",
>> +.owner = THIS_MODULE,
>> +.of_match_table = bcm2835_mbox_of_match,
>> +},
>> +.probe  = bcm2835_mbox_probe,
>> +.remove = bcm2835_mbox_remove,
>> +};
>> +module_platform_driver(bcm2835_mbox_driver);
>
> I have tested this driver and the firmware driver booting directly
> from the VideoCore bootloader (no uboot).
> The mailbox driver loads too late to turn on USB power:

Yeah, I have a patch on my branches that returns -EPROBE_DEFER when
trying to get a power domain and not finding the provider.  It was
rejected by the maintainers in favor of a proposed solution whose
description I didn't quite follow.

> This silences the warning:
> struct raspberrypi_power_domain raspberrypi_power_domain_usb = {
>  .base = {
>  .power_on_latency_ns = 6,

Oh, nice.  Thanks!


signature.asc
Description: PGP signature


Re: Re: [PATCH 2/3 v8] mailbox: Enable BCM2835 mailbox support

2015-05-08 Thread Eric Anholt
Alexander Stein  writes:

> On Thursday 07 May 2015, 12:54:20 wrote Eric Anholt:
>> Noralf Trønnes  writes:
>> 
>> > Den 05.05.2015 22:27, skrev Eric Anholt:
>> >> From: Lubomir Rintel 
>> >>
>> >> This mailbox driver provides a single mailbox channel to write 32-bit
>> >> values to the VPU and get a 32-bit response.  The Raspberry Pi
>> >> firmware uses this mailbox channel to implement firmware calls, while
>> >> Roku 2 (despite being derived from the same firmware tree) doesn't.
>> >>
>> >> The driver was originally submitted by Lubomir, based on the
>> >> out-of-tree 2708 mailbox driver.  Eric Anholt fixed it up for
>> >> upstreaming, with the major functional change being that it now has no
>> >> notion of multiple channels (since that is a firmware-dependent
>> >> concept) and instead the raspberrypi-firmware driver will do that
>> >> bit-twiddling in its own messages.
>> > ...
>> >> +static struct platform_driver bcm2835_mbox_driver = {
>> >> + .driver = {
>> >> + .name = "bcm2835-mbox",
>> >> + .owner = THIS_MODULE,
>> >> + .of_match_table = bcm2835_mbox_of_match,
>> >> + },
>> >> + .probe  = bcm2835_mbox_probe,
>> >> + .remove = bcm2835_mbox_remove,
>> >> +};
>> >> +module_platform_driver(bcm2835_mbox_driver);
>> >
>> > I have tested this driver and the firmware driver booting directly
>> > from the VideoCore bootloader (no uboot).
>> > The mailbox driver loads too late to turn on USB power:
>> 
>> Yeah, I have a patch on my branches that returns -EPROBE_DEFER when
>> trying to get a power domain and not finding the provider.  It was
>> rejected by the maintainers in favor of a proposed solution whose
>> description I didn't quite follow.
>
> Do you have a link for this thread?

https://lkml.org/lkml/2015/3/11/483


signature.asc
Description: PGP signature


[PATCH] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to SDRAM.

2015-05-04 Thread Eric Anholt
There exists a tiny MMU, configurable only by the VC (running the
closed firmware), which maps from the ARM's physical addresses to bus
addresses.  These bus addresses determine the caching behavior in the
VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top
2 bits.  The bits in the bus address mean:

>From the VideoCore processor:
0x0... L1 and L2 cache allocating and coherent
0x4... L1 non-allocating, but coherent. L2 allocating and coherent
0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent
0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent

>From the GPU peripherals (note: all peripherals bypass the L1
cache. The ARM will see this view once through the VC MMU):
0x0... Do not use
0x4... L1 non-allocating, and incoherent. L2 allocating and coherent.
0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent
0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent

The 2835 firmware always configures the MMU to turn ARM physical
addresses with 0x0 top bits to 0x4, meaning present in L2 but
incoherent with L1.  However, any bus addresses we were generating in
the kernel to be passed to a device had 0x0 bits.  That would be a
reserved (possibly totally incoherent) value if sent to a GPU
peripheral like USB, or L1 allocating if sent to the VC (like a
firmware property request).  By setting dma-ranges, all of the devices
below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and
friends return addresses with 0x4 bits and avoid cache incoherency.

This matches the behavior in the downstream 2708 kernel (see
BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h).

Signed-off-by: Eric Anholt 
Cc: popcorn...@gmail.com
---
 arch/arm/boot/dts/bcm2835.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 5734650..2df1b5c 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -15,6 +15,7 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x7e00 0x2000 0x0200>;
+   dma-ranges = <0x4000 0x 0x1f00>;
 
timer@7e003000 {
compatible = "brcm,bcm2835-system-timer";
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to SDRAM.

2015-05-04 Thread Eric Anholt
Noralf Trønnes  writes:

> Den 04.05.2015 21:33, skrev Eric Anholt:
>> There exists a tiny MMU, configurable only by the VC (running the
>> closed firmware), which maps from the ARM's physical addresses to bus
>> addresses.  These bus addresses determine the caching behavior in the
>> VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top
>> 2 bits.  The bits in the bus address mean:
>>
>>  From the VideoCore processor:
>> 0x0... L1 and L2 cache allocating and coherent
>> 0x4... L1 non-allocating, but coherent. L2 allocating and coherent
>> 0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent
>> 0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent
>>
>>  From the GPU peripherals (note: all peripherals bypass the L1
>> cache. The ARM will see this view once through the VC MMU):
>> 0x0... Do not use
>> 0x4... L1 non-allocating, and incoherent. L2 allocating and coherent.
>> 0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent
>> 0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent
>>
>> The 2835 firmware always configures the MMU to turn ARM physical
>> addresses with 0x0 top bits to 0x4, meaning present in L2 but
>> incoherent with L1.  However, any bus addresses we were generating in
>> the kernel to be passed to a device had 0x0 bits.  That would be a
>> reserved (possibly totally incoherent) value if sent to a GPU
>> peripheral like USB, or L1 allocating if sent to the VC (like a
>> firmware property request).  By setting dma-ranges, all of the devices
>> below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and
>> friends return addresses with 0x4 bits and avoid cache incoherency.
>>
>> This matches the behavior in the downstream 2708 kernel (see
>> BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h).
>>
>> Signed-off-by: Eric Anholt 
>> Cc: popcorn...@gmail.com
>> ---
>>   arch/arm/boot/dts/bcm2835.dtsi | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>> index 5734650..2df1b5c 100644
>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>> @@ -15,6 +15,7 @@
>>  #address-cells = <1>;
>>  #size-cells = <1>;
>>  ranges = <0x7e00 0x2000 0x0200>;
>> +dma-ranges = <0x4000 0x 0x1f00>;
>>   
>>  timer@7e003000 {
>>  compatible = "brcm,bcm2835-system-timer";
>
> This was quite a coincidence. I discovered the need for 'dma-ranges'
> yesterday while trying to get the downstream bcm2708_fb driver to
> work with ARCH_BCM2835. The driver is using the mailbox to get info
> about the framebuffer from the firmware. When it failed I discovered
> that the bus address was wrong.
>
> What I don't understand, is that mmc and spi works fine with a "wrong"
> bus address. It's only the framebuffer driver and the vchiq driver
> when using mailbox that fails.
>
> Tested-by: Noralf Trønnes 

Yeah, it was the mailbox driver I've been trying to merge, on pi2, that
made me get this patch together.  I'm suspicious that 0x0 works the same
as 0x4 for GPU peripherals (mmc, spi, vc4) on pi1, though I've had
occasional instability (something like 3 events per ~5000 tests) that I
sure hope is due to this.


signature.asc
Description: PGP signature


Re: [PATCH] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to SDRAM.

2015-05-05 Thread Eric Anholt
Stephen Warren  writes:

> On 05/04/2015 01:33 PM, Eric Anholt wrote:
>> There exists a tiny MMU, configurable only by the VC (running the
>> closed firmware), which maps from the ARM's physical addresses to bus
>> addresses.  These bus addresses determine the caching behavior in the
>> VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top
>> 2 bits.  The bits in the bus address mean:
>>
>>  From the VideoCore processor:
>> 0x0... L1 and L2 cache allocating and coherent
>> 0x4... L1 non-allocating, but coherent. L2 allocating and coherent
>> 0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent
>> 0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent
>>
>>  From the GPU peripherals (note: all peripherals bypass the L1
>> cache. The ARM will see this view once through the VC MMU):
>> 0x0... Do not use
>> 0x4... L1 non-allocating, and incoherent. L2 allocating and coherent.
>> 0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent
>> 0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent
>>
>> The 2835 firmware always configures the MMU to turn ARM physical
>> addresses with 0x0 top bits to 0x4, meaning present in L2 but
>> incoherent with L1.  However, any bus addresses we were generating in
>> the kernel to be passed to a device had 0x0 bits.  That would be a
>> reserved (possibly totally incoherent) value if sent to a GPU
>> peripheral like USB, or L1 allocating if sent to the VC (like a
>> firmware property request).  By setting dma-ranges, all of the devices
>> below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and
>> friends return addresses with 0x4 bits and avoid cache incoherency.
>>
>> This matches the behavior in the downstream 2708 kernel (see
>> BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h).
>
>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>
>>  #address-cells = <1>;
>>  #size-cells = <1>;
>>  ranges = <0x7e00 0x2000 0x0200>;
>> +dma-ranges = <0x4000 0x 0x1f00>;
>
> Oh well that's a nice and simple patch; I had been avoiding looking into 
> fixing the kernel for this since I was worried it'd be rather complex!
>
> I'm puzzled why the length cell of ranges and dma-ranges differs though? 
> Assuming there's a good explanation for that,

Nope, you're right, it should be 0x2000.  '0x1f' came from going
back from the '0x3f' on the pi2, but pi2 just has a chunk lost to the
bus mapping.


signature.asc
Description: PGP signature


[PATCH v2] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to SDRAM.

2015-05-05 Thread Eric Anholt
There exists a tiny MMU, configurable only by the VC (running the
closed firmware), which maps from the ARM's physical addresses to bus
addresses.  These bus addresses determine the caching behavior in the
VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top
2 bits.  The bits in the bus address mean:

>From the VideoCore processor:
0x0... L1 and L2 cache allocating and coherent
0x4... L1 non-allocating, but coherent. L2 allocating and coherent
0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent
0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent

>From the GPU peripherals (note: all peripherals bypass the L1
cache. The ARM will see this view once through the VC MMU):
0x0... Do not use
0x4... L1 non-allocating, and incoherent. L2 allocating and coherent.
0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent
0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent

The 2835 firmware always configures the MMU to turn ARM physical
addresses with 0x0 top bits to 0x4, meaning present in L2 but
incoherent with L1.  However, any bus addresses we were generating in
the kernel to be passed to a device had 0x0 bits.  That would be a
reserved (possibly totally incoherent) value if sent to a GPU
peripheral like USB, or L1 allocating if sent to the VC (like a
firmware property request).  By setting dma-ranges, all of the devices
below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and
friends return addresses with 0x4 bits and avoid cache incoherency.

This matches the behavior in the downstream 2708 kernel (see
BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h).

Signed-off-by: Eric Anholt 
Tested-by: Noralf Trønnes 
Acked-by: Stephen Warren 
Cc: popcorn...@gmail.com
---

v2: Fix length of the range from 0x1f00 to 0x2000, fixing the
translation for the last 16MB.

 arch/arm/boot/dts/bcm2835.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index eb33a8c..3c899b3 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -15,6 +15,7 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x7e00 0x2000 0x0200>;
+   dma-ranges = <0x4000 0x 0x2000>;
 
timer@7e003000 {
compatible = "brcm,bcm2835-system-timer";
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


<    1   2   3   4   5   6   7   8   9   10   >