blob: f519ef0e94d2f9cc5e45a608744489dfbd4c1f29 [file] [log] [blame]
/*
* Author: Tzu-Jung Lee <tjlee@ambarella.com>
*
* Copyright (C) 2012-2012, Ambarella, Inc.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/virtio_ids.h>
#include <linux/rpmsg.h>
#include <linux/dma-mapping.h>
#include <plat/remoteproc.h>
#include <plat/remoteproc_cfg.h>
/*
* The gen_rsc_table_* functions below fabricate the "resource table", which is
* used to initialize the vring configurations by the RPROC subsystem.
*
* The tables were originally meant to be loaded from ELF files on filesystem.
* It's a flexible and generic design, but requires extra maintenance out side
* the kernel space. So we currently code it plainly and directly here.
*
* The following illustrate the layout and structure of the table we use.
* Watch out the "sizeof()", since most of the structures here are embedded with
* variable-length array.
*
* 0x0000 &table
*
* < sizeof(*table) >
* < sizeof(u32) * table->num >
*
* 0x0014 &hdr (&table->offset)
*
* < sizeof(*hdr) >
*
* 0x0018 &vdev (&hdr->data)
*
* < sizeof(*vdev) >
*
* 0x0030 &vdev->ring[0] (&hdr->data)
*
* < sizeof(*vring) >
*
* 0x0044 &vdev->ring[1];
*
* < sizeof(*vring) >
* 0x0058
*/
static struct resource_table *gen_rsc_table_arm11(int *tablesz)
{
struct resource_table *table;
struct fw_rsc_hdr *hdr;
struct fw_rsc_vdev *vdev;
struct fw_rsc_vdev_vring *vring;
*tablesz = sizeof(*table) + sizeof(u32) * 1
+ sizeof(*hdr) + sizeof(*vdev)
+ sizeof(*vring) * 2;
table = kzalloc((*tablesz), GFP_KERNEL);
table->ver = 1;
table->num = 1;
table->offset[0] = sizeof(*table) + sizeof(u32) * table->num;
hdr = (void*)table + table->offset[0];
hdr->type = RSC_VDEV;
vdev = (void*)&hdr->data;
vdev->id = VIRTIO_ID_RPMSG;
vdev->notifyid = 124;
vdev->dfeatures = (1 << VIRTIO_RPMSG_F_NS);
vdev->config_len = 0;
vdev->num_of_vrings = 2;
vring = (void*)&vdev->vring[0];
vring->da = VRING_ARM11_TO_CA9_B;
vring->align = PAGE_SIZE;
vring->num = RPMSG_NUM_BUFS >> 1;
vring->notifyid = 111;
vring = (void*)&vdev->vring[1];
vring->da = VRING_CA9_B_TO_ARM11;
vring->align = PAGE_SIZE;
vring->num = RPMSG_NUM_BUFS >> 1;
vring->notifyid = 112;
return table;
}
static struct ambarella_rproc_pdata pdata_arm11 = {
.name = "ca9_b_and_arm11",
.firmware = "dummy",
.svq_tx_irq = -VRING_CA9_B_TO_ARM11_CLNT_IRQ,
.svq_rx_irq = VRING_CA9_B_TO_ARM11_HOST_IRQ,
.rvq_tx_irq = -VRING_ARM11_TO_CA9_B_CLNT_IRQ,
.rvq_rx_irq = VRING_ARM11_TO_CA9_B_HOST_IRQ,
.ops = NULL,
.buf_addr_pa = VRING_BUF_CA9_B_AND_ARM11,
.gen_rsc_table = gen_rsc_table_arm11,
};
struct platform_device ambarella_rproc_ca9_b_and_arm11_dev = {
.name = "ca9_b_and_arm11",
.id = VIRTIO_ID_RPMSG,
.resource = NULL,
.num_resources = 0,
.dev = {
.platform_data = &pdata_arm11,
.dma_mask = &ambarella_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};