Merge changes Ief2357bb,Iac66d768,Ib49a41f5 into msm-3.0

* changes:
  defconfig: 9615: Enable USB BAM driver
  msm: board-9615: Add USB BAM driver
  usb: gadget: SPS BAM-to-BAM - USB BAM driver
This commit is contained in:
Linux Build Service Account
2011-12-14 04:44:16 -08:00
committed by QuIC Gerrit Code Review
9 changed files with 379 additions and 0 deletions

View File

@@ -188,6 +188,7 @@ CONFIG_RTC_DRV_PM8XXX=y
CONFIG_MSM_SSBI=y CONFIG_MSM_SSBI=y
CONFIG_SPS=y CONFIG_SPS=y
CONFIG_SPS_SUPPORT_BAMDMA=y CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_USB_BAM=y
CONFIG_VFAT_FS=y CONFIG_VFAT_FS=y
CONFIG_TMPFS=y CONFIG_TMPFS=y
CONFIG_YAFFS_FS=y CONFIG_YAFFS_FS=y

View File

@@ -727,6 +727,39 @@ static int shelby_phy_init_seq[] = {
0x13, 0x83,/* set source impedance adjustment */ 0x13, 0x83,/* set source impedance adjustment */
-1}; -1};
#define USB_BAM_PHY_BASE 0x12502000
#define USB_BAM_PHY_SIZE 0x10000
#define A2_BAM_PHY_BASE 0x124C2000
static struct usb_bam_pipe_connect msm_usb_bam_connections[4][2] = {
[0][USB_TO_PEER_PERIPHERAL] = {
.src_phy_addr = USB_BAM_PHY_BASE,
.src_pipe_index = 11,
.dst_phy_addr = A2_BAM_PHY_BASE,
.dst_pipe_index = 0,
.data_fifo_base_offset = 0xf00,
.data_fifo_size = 0x400,
.desc_fifo_base_offset = 0x1300,
.desc_fifo_size = 0x300,
},
[0][PEER_PERIPHERAL_TO_USB] = {
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 1,
.dst_phy_addr = USB_BAM_PHY_BASE,
.dst_pipe_index = 10,
.data_fifo_base_offset = 0xa00,
.data_fifo_size = 0x400,
.desc_fifo_base_offset = 0xe00,
.desc_fifo_size = 0x100,
},
};
static struct msm_usb_bam_platform_data msm_usb_bam_pdata = {
.connections = &msm_usb_bam_connections[0][0],
.usb_bam_phy_base = USB_BAM_PHY_BASE,
.usb_bam_phy_size = USB_BAM_PHY_SIZE,
.usb_bam_num_pipes = 32,
};
static struct msm_otg_platform_data msm_otg_pdata = { static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG, .mode = USB_OTG,
.otg_control = OTG_PHY_CONTROL, .otg_control = OTG_PHY_CONTROL,
@@ -781,6 +814,7 @@ static struct platform_device *common_devices[] = {
&msm_device_otg, &msm_device_otg,
&msm_device_gadget_peripheral, &msm_device_gadget_peripheral,
&msm_device_hsusb_host, &msm_device_hsusb_host,
&msm_device_usb_bam,
&android_usb_device, &android_usb_device,
&msm9615_device_uart_gsbi4, &msm9615_device_uart_gsbi4,
&msm9615_device_ext_2p95v_vreg, &msm9615_device_ext_2p95v_vreg,
@@ -833,6 +867,7 @@ static void __init msm9615_common_init(void)
msm_device_otg.dev.platform_data = &msm_otg_pdata; msm_device_otg.dev.platform_data = &msm_otg_pdata;
msm_otg_pdata.phy_init_seq = shelby_phy_init_seq; msm_otg_pdata.phy_init_seq = shelby_phy_init_seq;
msm_device_usb_bam.dev.platform_data = &msm_usb_bam_pdata;
platform_add_devices(common_devices, ARRAY_SIZE(common_devices)); platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
acpuclk_init(&acpuclk_9615_soc_data); acpuclk_init(&acpuclk_9615_soc_data);

View File

@@ -99,6 +99,9 @@ struct platform_device msm9615_device_dmov = {
}, },
}; };
#define MSM_USB_BAM_BASE 0x12502000
#define MSM_USB_BAM_SIZE 0x3DFFF
static struct resource resources_otg[] = { static struct resource resources_otg[] = {
{ {
.start = MSM9615_HSUSB_PHYS, .start = MSM9615_HSUSB_PHYS,
@@ -135,6 +138,28 @@ static struct resource resources_hsusb[] = {
}, },
}; };
static struct resource resources_usb_bam[] = {
{
.name = "usb_bam_addr",
.start = MSM_USB_BAM_BASE,
.end = MSM_USB_BAM_BASE + MSM_USB_BAM_SIZE,
.flags = IORESOURCE_MEM,
},
{
.name = "usb_bam_irq",
.start = USB1_HS_BAM_IRQ,
.end = USB1_HS_BAM_IRQ,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_usb_bam = {
.name = "usb_bam",
.id = -1,
.num_resources = ARRAY_SIZE(resources_usb_bam),
.resource = resources_usb_bam,
};
struct platform_device msm_device_gadget_peripheral = { struct platform_device msm_device_gadget_peripheral = {
.name = "msm_hsusb", .name = "msm_hsusb",
.id = -1, .id = -1,

View File

@@ -118,6 +118,7 @@ extern struct platform_device msm_gsbi12_qup_i2c_device;
extern struct platform_device msm_slim_ctrl; extern struct platform_device msm_slim_ctrl;
extern struct platform_device msm_device_sps; extern struct platform_device msm_device_sps;
extern struct platform_device msm_device_usb_bam;
extern struct platform_device msm_device_sps_apq8064; extern struct platform_device msm_device_sps_apq8064;
extern struct platform_device msm_device_bam_dmux; extern struct platform_device msm_device_bam_dmux;
extern struct platform_device msm_device_smd; extern struct platform_device msm_device_smd;

View File

@@ -0,0 +1,40 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only 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.
*/
#ifndef _USB_BAM_H_
#define _USB_BAM_H_
/**
* Connect USB-to-Periperal SPS connection.
*
* This function returns the allocated pipes number.
*
* @idx - Connection index.
*
* @src_pipe_idx - allocated pipe index - USB as a
* source (output)
*
* @dst_pipe_idx - allocated pipe index - USB as a
* destination (output)
*
* @return 0 on success, negative value on error
*
*/
#ifdef CONFIG_USB_BAM
int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx);
#else
int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx)
{
return -ENODEV;
}
#endif
#endif /* _USB_BAM_H_ */

View File

@@ -23,6 +23,14 @@ config SPS
2. Peripheral-to-Memory. 2. Peripheral-to-Memory.
3. Memory-to-Memory. 3. Memory-to-Memory.
config USB_BAM
boolean "USB BAM Driver"
depends on SPS && USB_GADGET
help
Enabling this option adds USB BAM Driver.
USB BAM driver was added to supports SPS Peripheral-to-Peripheral
transfers between the USB and other peripheral.
config SPS_SUPPORT_BAMDMA config SPS_SUPPORT_BAMDMA
bool "SPS support BAM DMA" bool "SPS support BAM DMA"
depends on SPS depends on SPS

View File

@@ -2,4 +2,5 @@
# Makefile for the MSM specific device drivers. # Makefile for the MSM specific device drivers.
# #
obj-$(CONFIG_MSM_SSBI) += ssbi.o obj-$(CONFIG_MSM_SSBI) += ssbi.o
obj-$(CONFIG_USB_BAM) += usb_bam.o
obj-$(CONFIG_SPS) += sps/ obj-$(CONFIG_SPS) += sps/

View File

@@ -0,0 +1,238 @@
/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only 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.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/usb/msm_hsusb.h>
#include <mach/usb_bam.h>
#include <mach/sps.h>
#define USB_SUMMING_THRESHOLD 512
#define CONNECTIONS_NUM 4
static struct sps_bam_props usb_props;
static struct sps_pipe *sps_pipes[CONNECTIONS_NUM][2];
static struct sps_connect sps_connections[CONNECTIONS_NUM][2];
static struct sps_mem_buffer data_mem_buf[CONNECTIONS_NUM][2];
static struct sps_mem_buffer desc_mem_buf[CONNECTIONS_NUM][2];
static struct platform_device *usb_bam_pdev;
struct usb_bam_connect_info {
u8 idx;
u8 *src_pipe;
u8 *dst_pipe;
bool enabled;
};
static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
static int connect_pipe(u8 connection_idx, enum usb_bam_pipe_dir pipe_dir,
u8 *usb_pipe_idx)
{
int ret;
struct sps_pipe *pipe = sps_pipes[connection_idx][pipe_dir];
struct sps_connect *connection =
&sps_connections[connection_idx][pipe_dir];
struct msm_usb_bam_platform_data *pdata =
(struct msm_usb_bam_platform_data *)
(usb_bam_pdev->dev.platform_data);
struct usb_bam_pipe_connect *pipe_connection =
(struct usb_bam_pipe_connect *)(pdata->connections +
(2*connection_idx+pipe_dir));
pipe = sps_alloc_endpoint();
if (pipe == NULL) {
pr_err("%s: sps_alloc_endpoint failed\n", __func__);
return -ENOMEM;
}
ret = sps_get_config(pipe, connection);
if (ret) {
pr_err("%s: tx get config failed %d\n", __func__, ret);
goto get_config_failed;
}
ret = sps_phy2h(pipe_connection->src_phy_addr, &(connection->source));
if (ret) {
pr_err("%s: sps_phy2h failed (src BAM) %d\n", __func__, ret);
goto get_config_failed;
}
connection->src_pipe_index = pipe_connection->src_pipe_index;
ret = sps_phy2h(pipe_connection->dst_phy_addr,
&(connection->destination));
if (ret) {
pr_err("%s: sps_phy2h failed (dst BAM) %d\n", __func__, ret);
goto get_config_failed;
}
connection->dest_pipe_index = pipe_connection->dst_pipe_index;
if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
connection->mode = SPS_MODE_SRC;
*usb_pipe_idx = connection->src_pipe_index;
} else {
connection->mode = SPS_MODE_DEST;
*usb_pipe_idx = connection->dest_pipe_index;
}
ret = sps_setup_bam2bam_fifo(
&data_mem_buf[connection_idx][pipe_dir],
pipe_connection->data_fifo_base_offset,
pipe_connection->data_fifo_size, 1);
if (ret) {
pr_err("%s: data fifo setup failure %d\n", __func__, ret);
goto fifo_setup_error;
}
connection->data = data_mem_buf[connection_idx][pipe_dir];
ret = sps_setup_bam2bam_fifo(
&desc_mem_buf[connection_idx][pipe_dir],
pipe_connection->desc_fifo_base_offset,
pipe_connection->desc_fifo_size, 1);
if (ret) {
pr_err("%s: desc. fifo setup failure %d\n", __func__, ret);
goto fifo_setup_error;
}
connection->desc = desc_mem_buf[connection_idx][pipe_dir];
connection->event_thresh = 512;
ret = sps_connect(pipe, connection);
if (ret < 0) {
pr_err("%s: tx connect error %d\n", __func__, ret);
goto error;
}
return 0;
error:
sps_disconnect(pipe);
fifo_setup_error:
get_config_failed:
sps_free_endpoint(pipe);
return ret;
}
int usb_bam_connect(u8 idx, u8 *src_pipe_idx, u8 *dst_pipe_idx)
{
struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
int ret;
if (idx >= CONNECTIONS_NUM) {
pr_err("%s: Invalid connection index\n",
__func__);
return -EINVAL;
}
if (connection->enabled) {
pr_info("%s: connection %d was already established\n",
__func__, idx);
return 0;
}
connection->src_pipe = src_pipe_idx;
connection->dst_pipe = dst_pipe_idx;
connection->idx = idx;
/* open USB -> Peripheral pipe */
ret = connect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL,
connection->src_pipe);
if (ret) {
pr_err("%s: src pipe connection failure\n", __func__);
return ret;
}
/* open Peripheral -> USB pipe */
ret = connect_pipe(connection->idx, PEER_PERIPHERAL_TO_USB,
connection->dst_pipe);
if (ret) {
pr_err("%s: dst pipe connection failure\n", __func__);
return ret;
}
connection->enabled = 1;
return 0;
}
static int usb_bam_init(void)
{
u32 h_usb;
int ret;
void *usb_virt_addr;
struct msm_usb_bam_platform_data *pdata =
(struct msm_usb_bam_platform_data *)
(usb_bam_pdev->dev.platform_data);
usb_virt_addr = ioremap_nocache(
pdata->usb_bam_phy_base,
pdata->usb_bam_phy_size);
if (!usb_virt_addr) {
pr_err("%s: ioremap failed\n", __func__);
return -ENOMEM;
}
usb_props.phys_addr = pdata->usb_bam_phy_base;
usb_props.virt_addr = usb_virt_addr;
usb_props.virt_size = pdata->usb_bam_phy_size;
usb_props.irq = USB1_HS_BAM_IRQ;
usb_props.num_pipes = pdata->usb_bam_num_pipes;
usb_props.summing_threshold = USB_SUMMING_THRESHOLD;
ret = sps_register_bam_device(&usb_props, &h_usb);
if (ret < 0) {
pr_err("%s: register bam error %d\n", __func__, ret);
return -EFAULT;
}
return 0;
}
static int usb_bam_probe(struct platform_device *pdev)
{
int ret, i;
dev_dbg(&pdev->dev, "usb_bam_probe\n");
for (i = 0; i < CONNECTIONS_NUM; i++)
usb_bam_connections[i].enabled = 0;
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "missing platform_data\n");
return -ENODEV;
}
usb_bam_pdev = pdev;
ret = usb_bam_init();
if (ret) {
dev_err(&pdev->dev, "failed to get platform resource mem\n");
return ret;
}
return 0;
}
static struct platform_driver usb_bam_driver = {
.probe = usb_bam_probe,
.driver = { .name = "usb_bam", },
};
static int __init init(void)
{
return platform_driver_register(&usb_bam_driver);
}
module_init(init);
static void __exit cleanup(void)
{
platform_driver_unregister(&usb_bam_driver);
}
module_exit(cleanup);
MODULE_DESCRIPTION("MSM USB BAM DRIVER");
MODULE_LICENSE("GPL v2");

View File

@@ -131,6 +131,19 @@ enum usb_chg_type {
USB_ACA_DOCK_CHARGER, USB_ACA_DOCK_CHARGER,
}; };
/**
* SPS Pipes direction.
*
* USB_TO_PEER_PERIPHERAL USB (as Producer) to other
* peer peripheral.
* PEER_PERIPHERAL_TO_USB Other Peripheral to
* USB (as consumer).
*/
enum usb_bam_pipe_dir {
USB_TO_PEER_PERIPHERAL,
PEER_PERIPHERAL_TO_USB,
};
/** /**
* struct msm_otg_platform_data - platform device data * struct msm_otg_platform_data - platform device data
* for msm_otg driver. * for msm_otg driver.
@@ -258,4 +271,21 @@ struct msm_hsic_host_platform_data {
unsigned hub_reset; unsigned hub_reset;
}; };
struct usb_bam_pipe_connect {
u32 src_phy_addr;
int src_pipe_index;
u32 dst_phy_addr;
int dst_pipe_index;
u32 data_fifo_base_offset;
u32 data_fifo_size;
u32 desc_fifo_base_offset;
u32 desc_fifo_size;
};
struct msm_usb_bam_platform_data {
struct usb_bam_pipe_connect *connections;
unsigned long usb_bam_phy_base;
unsigned long usb_bam_phy_size;
int usb_bam_num_pipes;
};
#endif #endif