From f2da2b163827a075c98f1897801c90bf736784a3 Mon Sep 17 00:00:00 2001
From: Anil Kumar Ch <anilkumar@ti.com>
Date: Sun, 6 Nov 2011 02:46:12 +0530
Subject: [PATCH 2/7] can: d_can: Added platform data for am33xx device

This patch adds the platform data needed by the driver. Added the
resources to the difference d_can instances.

Initialization of message ram is necessary to read/write the message object
from/into the message RAM

Signed-off-by: Anil Kumar Ch <anilkumar@ti.com>
---
 arch/arm/mach-omap2/board-am335xevm.c    |  131 ++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/clock33xx_data.c     |   18 ++++
 arch/arm/mach-omap2/mux33xx.c            |    8 +-
 arch/arm/plat-omap/include/plat/am33xx.h |    3 +
 4 files changed, 156 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
index c84857e..6773f3b 100644
--- a/arch/arm/mach-omap2/board-am335xevm.c
+++ b/arch/arm/mach-omap2/board-am335xevm.c
@@ -24,6 +24,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/platform_device.h>
+#include <linux/can/platform/d_can.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/wl12xx.h>
@@ -50,6 +51,7 @@
 /* LCD controller is similar to DA850 */
 #include <video/da8xx-fb.h>
 
+#include "control.h"
 #include "board-flash.h"
 #include "mux.h"
 #include "devices.h"
@@ -991,6 +993,133 @@ static void mmc2_wl12xx_init(int evm_id, int profile)
 	return;
 }
 
+#define AM33XX_D_CAN_RAM_BASE		0x1000
+#define AM33XX_D_CAN_NUM_MSG_OBJS	64
+#define AM33XX_D_CAN_VERSION		0x1
+#define AM33XX_CTL_DCAN_RAMINIT_OFFSET	0x644
+#define AM33XX_D_CAN_RAMINIT_START(n)	(0x1 << n)
+
+static void d_can_hw_raminit(unsigned int instance)
+{
+	u32 raminit_reg_val;
+
+	/* Read the value */
+	raminit_reg_val = __raw_readl(AM33XX_CTRL_REGADDR(
+				AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+
+	/* Modify by setting "0" */
+	raminit_reg_val &= ~AM33XX_D_CAN_RAMINIT_START(instance);
+	__raw_writel(raminit_reg_val, AM33XX_CTRL_REGADDR(
+				AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+
+	/* Reset to one */
+	raminit_reg_val |= AM33XX_D_CAN_RAMINIT_START(instance);
+	__raw_writel(raminit_reg_val, AM33XX_CTRL_REGADDR(
+			AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+	udelay(10);
+}
+
+static struct d_can_platform_data am33xx_evm_d_can_pdata = {
+	.d_can_offset		= 0,
+	.d_can_ram_offset	= AM33XX_D_CAN_RAM_BASE,
+	.num_of_msg_objs	= AM33XX_D_CAN_NUM_MSG_OBJS,
+	.dma_support		= false,
+	.test_mode_enable	= false,
+	.parity_check		= false,
+	.version		= AM33XX_D_CAN_VERSION,
+	.hw_raminit		= d_can_hw_raminit,
+};
+
+static struct resource am33xx_d_can0_resources[] = {
+	{
+		.start	= AM33XX_D_CAN0_BASE,
+		.end	= AM33XX_D_CAN0_BASE + 0x3FFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "d_can_int0",
+		.start	= AM33XX_IRQ_DCAN0_0,
+		.end	= AM33XX_IRQ_DCAN0_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "d_can_int1",
+		.start	= AM33XX_IRQ_DCAN0_1,
+		.end	= AM33XX_IRQ_DCAN0_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device am33xx_d_can0_device = {
+	.dev		= {
+		.platform_data = &am33xx_evm_d_can_pdata,
+	},
+	.name		= "d_can",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(am33xx_d_can0_resources),
+	.resource	= am33xx_d_can0_resources,
+};
+
+static struct pinmux_config d_can0_pin_mux[] = {
+	{"uart1_ctsn.d_can0_tx", OMAP_MUX_MODE2 | AM33XX_PULL_ENBL},
+	{"uart1_rtsn.d_can0_rx", OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP},
+	{NULL, 0},
+};
+
+static void d_can0_init(int evm_id, int profile)
+{
+	/* For instance 0 */
+	if (profile == PROFILE_1) {
+		setup_pin_mux(d_can0_pin_mux);
+		platform_device_register(&am33xx_d_can0_device);
+	}
+}
+
+/* DCAN instnace 1 specific resources */
+static struct resource am33xx_d_can1_resources[] = {
+	{
+		.start	= AM33XX_D_CAN1_BASE,
+		.end	= AM33XX_D_CAN1_BASE + 0x3FFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "d_can_int0",
+		.start	= AM33XX_IRQ_DCAN1_0,
+		.end	= AM33XX_IRQ_DCAN1_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "d_can_int1",
+		.start	= AM33XX_IRQ_DCAN1_1,
+		.end	= AM33XX_IRQ_DCAN1_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device am33xx_d_can1_device = {
+	.dev		= {
+		.platform_data = &am33xx_evm_d_can_pdata,
+	},
+	.name		= "d_can",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(am33xx_d_can1_resources),
+	.resource	= am33xx_d_can1_resources,
+};
+
+static struct pinmux_config d_can1_pin_mux[] = {
+	{"uart1_rxd.d_can1_tx", OMAP_MUX_MODE2 | AM33XX_PULL_ENBL},
+	{"uart1_txd.d_can1_rx", OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP},
+	{NULL, 0},
+};
+
+static void d_can1_init(int evm_id, int profile)
+{
+	/* For instance 1 */
+	if (profile == PROFILE_4) {
+		setup_pin_mux(d_can1_pin_mux);
+		platform_device_register(&am33xx_d_can1_device);
+	}
+}
 static void uart1_wl12xx_init(int evm_id, int profile)
 {
 	setup_pin_mux(uart1_wl12xx_pin_mux);
@@ -1194,6 +1323,8 @@ static struct evm_dev_cfg gen_purp_evm_dev_cfg[] = {
 	{uart1_wl12xx_init,	DEV_ON_BASEBOARD, (PROFILE_0 | PROFILE_3 |
 								PROFILE_5)},
 	{wl12xx_init,	DEV_ON_BASEBOARD, (PROFILE_0 | PROFILE_3 | PROFILE_5)},
+	{d_can0_init,	DEV_ON_BASEBOARD, PROFILE_1},
+	{d_can1_init,	DEV_ON_BASEBOARD, PROFILE_4},
 	{NULL, 0, 0},
 };
 
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 6763c59..d8670f2 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -421,6 +421,22 @@ static struct clk dcan1_fck = {
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk dcan0_ick = {
+	.name           = "dcan0_ick",
+	.parent		= &dpll_per_m2_ck ,
+	.ops		= &clkops_null,
+	.clkdm_name	= "l4ls_clkdm",
+	.recalc         = &followparent_recalc,
+};
+
+static struct clk dcan1_ick = {
+	.name           = "dcan1_ick",
+	.parent		= &dpll_per_m2_ck ,
+	.ops		= &clkops_null,
+	.clkdm_name	= "l4ls_clkdm",
+	.recalc         = &followparent_recalc,
+};
+
 static struct clk debugss_fck = {
 	.name		= "debugss_fck",
 	.ops		= &clkops_omap2_dflt,
@@ -1771,6 +1787,8 @@ static struct omap_clk am33xx_clks[] = {
 	CLK("cpsw.0",	NULL,			&cpgmac0_fck,	CK_AM33XX),
 	CLK(NULL,	"dcan0_fck",		&dcan0_fck,	CK_AM33XX),
 	CLK(NULL,	"dcan1_fck",		&dcan1_fck,	CK_AM33XX),
+	CLK(NULL,	"dcan0_ick",		&dcan0_ick,	CK_AM33XX),
+	CLK(NULL,	"dcan1_ick",		&dcan1_ick,	CK_AM33XX),
 	CLK(NULL,	"debugss_fck",		&debugss_fck,	CK_AM33XX),
 	CLK(NULL,	"elm_fck",		&elm_fck,	CK_AM33XX),
 	CLK(NULL,	"emif_fck",		&emif_fck,	CK_AM33XX),
diff --git a/arch/arm/mach-omap2/mux33xx.c b/arch/arm/mach-omap2/mux33xx.c
index 0286c4f..8232b46 100644
--- a/arch/arm/mach-omap2/mux33xx.c
+++ b/arch/arm/mach-omap2/mux33xx.c
@@ -315,16 +315,16 @@ static struct omap_mux __initdata am33xx_muxmodes[] = {
 		"uart0_txd", "spi1_cs1", NULL, NULL,
 		NULL, NULL, NULL, NULL),
 	_AM33XX_MUXENTRY(UART1_CTSN, 0,
-		"uart1_ctsn", NULL, NULL, NULL,
+		"uart1_ctsn", NULL, "d_can0_tx", NULL,
 		"spi1_cs0", NULL, NULL, NULL),
 	_AM33XX_MUXENTRY(UART1_RTSN, 0,
-		"uart1_rtsn", NULL, NULL, NULL,
+		"uart1_rtsn", NULL, "d_can0_rx", NULL,
 		"spi1_cs1", NULL, NULL, NULL),
 	_AM33XX_MUXENTRY(UART1_RXD, 0,
-		"uart1_rxd", "mmc1_sdwp", NULL, NULL,
+		"uart1_rxd", "mmc1_sdwp", "d_can1_tx", NULL,
 		NULL, NULL, NULL, NULL),
 	_AM33XX_MUXENTRY(UART1_TXD, 0,
-		"uart1_txd", "mmc2_sdwp", NULL, NULL,
+		"uart1_txd", "mmc2_sdwp", "d_can1_rx", NULL,
 		NULL, NULL, NULL, NULL),
 	_AM33XX_MUXENTRY(I2C0_SDA, 0,
 		"i2c0_sda", NULL, NULL, NULL,
diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h
index a77c38e..cfd1883 100644
--- a/arch/arm/plat-omap/include/plat/am33xx.h
+++ b/arch/arm/plat-omap/include/plat/am33xx.h
@@ -30,6 +30,9 @@
 #define AM33XX_TSC_BASE		0x44E0D000
 #define AM33XX_RTC_BASE		0x44E3E000
 
+#define AM33XX_D_CAN0_BASE	0x481CC000
+#define AM33XX_D_CAN1_BASE	0x481D0000
+
 #define AM33XX_ASP0_BASE	0x48038000
 #define AM33XX_ASP1_BASE	0x4803C000
 
-- 
1.7.2.5

