openwrt/target/linux/bcm27xx/patches-4.19/950-0467-vchiq-Add-36-bit-address-support.patch
Adrian Schmutzler 7d7aa2fd92 brcm2708: rename target to bcm27xx
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>
2020-02-14 14:10:51 +01:00

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;
};