mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 17:48:58 +00:00
7d7aa2fd92
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
197 lines
6.7 KiB
Diff
197 lines
6.7 KiB
Diff
From d5c6191cc94b358de183cc8c88a5722a79445202 Mon Sep 17 00:00:00 2001
|
|
From: Phil Elwell <phil@raspberrypi.org>
|
|
Date: Thu, 1 Nov 2018 17:31:37 +0000
|
|
Subject: [PATCH] vchiq: Add 36-bit address support
|
|
|
|
Conditional on a new compatible string, change the pagelist encoding
|
|
such that the top 24 bits are the pfn, leaving 8 bits for run length
|
|
(-1).
|
|
|
|
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
|
---
|
|
.../interface/vchiq_arm/vchiq_2835_arm.c | 90 ++++++++++++++-----
|
|
.../interface/vchiq_arm/vchiq_arm.c | 6 ++
|
|
.../interface/vchiq_arm/vchiq_arm.h | 1 +
|
|
3 files changed, 75 insertions(+), 22 deletions(-)
|
|
|
|
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
|
|
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
|
|
@@ -47,6 +47,8 @@
|
|
#include <soc/bcm2835/raspberrypi-firmware.h>
|
|
|
|
#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32)
|
|
+#define VC_SAFE(x) (g_use_36bit_addrs ? ((u32)(x) | 0xc0000000) : (u32)(x))
|
|
+#define IS_VC_SAFE(x) (g_use_36bit_addrs ? !((x) & ~0x3fffffffull) : 1)
|
|
|
|
#include "vchiq_arm.h"
|
|
#include "vchiq_connected.h"
|
|
@@ -96,6 +98,7 @@ static void __iomem *g_regs;
|
|
*/
|
|
static unsigned int g_cache_line_size;
|
|
static struct dma_pool *g_dma_pool;
|
|
+static unsigned int g_use_36bit_addrs = 0;
|
|
static unsigned int g_fragments_size;
|
|
static char *g_fragments_base;
|
|
static char *g_free_fragments;
|
|
@@ -139,6 +142,8 @@ int vchiq_platform_init(struct platform_
|
|
g_cache_line_size = drvdata->cache_line_size;
|
|
g_fragments_size = 2 * g_cache_line_size;
|
|
|
|
+ g_use_36bit_addrs = (dev->dma_pfn_offset == 0);
|
|
+
|
|
/* Allocate space for the channels in coherent memory */
|
|
slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE);
|
|
frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS);
|
|
@@ -150,14 +155,21 @@ int vchiq_platform_init(struct platform_
|
|
return -ENOMEM;
|
|
}
|
|
|
|
+ if (!IS_VC_SAFE(slot_phys)) {
|
|
+ dev_err(dev, "allocated DMA memory %pad is not VC-safe\n",
|
|
+ &slot_phys);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0);
|
|
+ channelbase = VC_SAFE(slot_phys);
|
|
|
|
vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size);
|
|
if (!vchiq_slot_zero)
|
|
return -EINVAL;
|
|
|
|
vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] =
|
|
- (int)slot_phys + slot_mem_size;
|
|
+ channelbase + slot_mem_size;
|
|
vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] =
|
|
MAX_FRAGMENTS;
|
|
|
|
@@ -193,7 +205,6 @@ int vchiq_platform_init(struct platform_
|
|
}
|
|
|
|
/* Send the base address of the slots to VideoCore */
|
|
- channelbase = slot_phys;
|
|
err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT,
|
|
&channelbase, sizeof(channelbase));
|
|
if (err || channelbase) {
|
|
@@ -282,7 +293,7 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu
|
|
return VCHIQ_ERROR;
|
|
|
|
bulk->handle = memhandle;
|
|
- bulk->data = (void *)(unsigned long)pagelistinfo->dma_addr;
|
|
+ bulk->data = (void *)VC_SAFE(pagelistinfo->dma_addr);
|
|
|
|
/*
|
|
* Store the pagelistinfo address in remote_data,
|
|
@@ -570,25 +581,60 @@ create_pagelist(char __user *buf, size_t
|
|
|
|
/* Combine adjacent blocks for performance */
|
|
k = 0;
|
|
- for_each_sg(scatterlist, sg, dma_buffers, i) {
|
|
- u32 len = sg_dma_len(sg);
|
|
- u32 addr = sg_dma_address(sg);
|
|
-
|
|
- /* Note: addrs is the address + page_count - 1
|
|
- * The firmware expects blocks after the first to be page-
|
|
- * aligned and a multiple of the page size
|
|
- */
|
|
- WARN_ON(len == 0);
|
|
- WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
|
|
- WARN_ON(i && (addr & ~PAGE_MASK));
|
|
- if (k > 0 &&
|
|
- ((addrs[k - 1] & PAGE_MASK) +
|
|
- (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT))
|
|
- == (addr & PAGE_MASK))
|
|
- addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT);
|
|
- else
|
|
- addrs[k++] = (addr & PAGE_MASK) |
|
|
- (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1);
|
|
+ if (g_use_36bit_addrs) {
|
|
+ for_each_sg(scatterlist, sg, dma_buffers, i) {
|
|
+ u32 len = sg_dma_len(sg);
|
|
+ u64 addr = sg_dma_address(sg);
|
|
+ u32 page_id = (u32)((addr >> 4) & ~0xff);
|
|
+ u32 sg_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
+
|
|
+ /* Note: addrs is the address + page_count - 1
|
|
+ * The firmware expects blocks after the first to be page-
|
|
+ * aligned and a multiple of the page size
|
|
+ */
|
|
+ WARN_ON(len == 0);
|
|
+ WARN_ON(i &&
|
|
+ (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
|
|
+ WARN_ON(i && (addr & ~PAGE_MASK));
|
|
+ WARN_ON(upper_32_bits(addr) > 0xf);
|
|
+ if (k > 0 &&
|
|
+ ((addrs[k - 1] & ~0xff) +
|
|
+ (((addrs[k - 1] & 0xff) + 1) << 8)
|
|
+ == page_id)) {
|
|
+ u32 inc_pages = min(sg_pages,
|
|
+ 0xff - (addrs[k - 1] & 0xff));
|
|
+ addrs[k - 1] += inc_pages;
|
|
+ page_id += inc_pages << 8;
|
|
+ sg_pages -= inc_pages;
|
|
+ }
|
|
+ while (sg_pages) {
|
|
+ u32 inc_pages = min(sg_pages, 0x100u);
|
|
+ addrs[k++] = page_id | (inc_pages - 1);
|
|
+ page_id += inc_pages << 8;
|
|
+ sg_pages -= inc_pages;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ for_each_sg(scatterlist, sg, dma_buffers, i) {
|
|
+ u32 len = sg_dma_len(sg);
|
|
+ u32 addr = VC_SAFE(sg_dma_address(sg));
|
|
+ u32 new_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
+
|
|
+ /* Note: addrs is the address + page_count - 1
|
|
+ * The firmware expects blocks after the first to be page-
|
|
+ * aligned and a multiple of the page size
|
|
+ */
|
|
+ WARN_ON(len == 0);
|
|
+ WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
|
|
+ WARN_ON(i && (addr & ~PAGE_MASK));
|
|
+ if (k > 0 &&
|
|
+ ((addrs[k - 1] & PAGE_MASK) +
|
|
+ (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT))
|
|
+ == (addr & PAGE_MASK))
|
|
+ addrs[k - 1] += new_pages;
|
|
+ else
|
|
+ addrs[k++] = (addr & PAGE_MASK) | (new_pages - 1);
|
|
+ }
|
|
}
|
|
|
|
/* Partial cache lines (fragments) require special measures */
|
|
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
|
|
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
|
|
@@ -181,6 +181,11 @@ static struct vchiq_drvdata bcm2836_drvd
|
|
.cache_line_size = 64,
|
|
};
|
|
|
|
+static struct vchiq_drvdata bcm2838_drvdata = {
|
|
+ .cache_line_size = 64,
|
|
+ .use_36bit_addrs = true,
|
|
+};
|
|
+
|
|
static const char *const ioctl_names[] = {
|
|
"CONNECT",
|
|
"SHUTDOWN",
|
|
@@ -3618,6 +3623,7 @@ vchiq_register_child(struct platform_dev
|
|
static const struct of_device_id vchiq_of_match[] = {
|
|
{ .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata },
|
|
{ .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata },
|
|
+ { .compatible = "brcm,bcm2838-vchiq", .data = &bcm2838_drvdata },
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, vchiq_of_match);
|
|
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
|
|
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
|
|
@@ -125,6 +125,7 @@ typedef struct vchiq_arm_state_struct {
|
|
|
|
struct vchiq_drvdata {
|
|
const unsigned int cache_line_size;
|
|
+ const bool use_36bit_addrs;
|
|
struct rpi_firmware *fw;
|
|
};
|
|
|