Last active
December 25, 2015 02:29
-
-
Save notro/6903349 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c | |
index 5662c1a..3cf8793 100644 | |
--- a/arch/arm/mach-bcm2708/bcm2708.c | |
+++ b/arch/arm/mach-bcm2708/bcm2708.c | |
@@ -21,7 +21,13 @@ | |
#include <linux/init.h> | |
#include <linux/device.h> | |
#include <linux/dma-mapping.h> | |
+#include <linux/irqdomain.h> | |
#include <linux/serial_8250.h> | |
+#include <linux/of_address.h> | |
+#include <linux/of_platform.h> | |
#include <linux/platform_device.h> | |
#include <linux/syscore_ops.h> | |
#include <linux/interrupt.h> | |
@@ -56,6 +62,11 @@ | |
#include <linux/delay.h> | |
+#include <linux/clk-provider.h> | |
#include "bcm2708.h" | |
#include "armctrl.h" | |
#include "clock.h" | |
@@ -545,7 +562,7 @@ static struct platform_device bcm2708_spi_device = { | |
.num_resources = ARRAY_SIZE(bcm2708_spi_resources), | |
.resource = bcm2708_spi_resources, | |
}; | |
- | |
+/* | |
#ifdef CONFIG_BCM2708_SPIDEV | |
static struct spi_board_info bcm2708_spi_devices[] = { | |
#ifdef CONFIG_SPI_SPIDEV | |
@@ -565,7 +582,7 @@ static struct spi_board_info bcm2708_spi_devices[] = { | |
#endif | |
}; | |
#endif | |
- | |
+*/ | |
static struct resource bcm2708_bsc0_resources[] = { | |
{ | |
.start = BSC0_BASE, | |
@@ -690,10 +707,126 @@ static void bcm2708_power_off(void) | |
} | |
} | |
+void __init bcm2708_dt_clk_init(void) | |
+{ | |
+ struct device_node *np = NULL; | |
+ struct of_phandle_args clkspec; | |
+ int rc; | |
+ u32 rate; | |
+ const __be32 *reg; | |
+ u64 addr; | |
+ const __be32 *addrp; | |
+ struct clk *dt_clk; | |
+ struct clk_lookup *lookup; | |
+ char *dev_id; | |
+ | |
+ while((np = of_find_all_nodes(np)) != NULL) { | |
+ | |
+ rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0, &clkspec); | |
+ if (rc) | |
+ continue; | |
+ pr_info("bcm2708: Trying to find clock for '%s'...\n", np->full_name); | |
+ | |
+ /* find device name, taken from of_device_make_bus_id() */ | |
+ addr = OF_BAD_ADDR; | |
+ reg = of_get_property(np, "reg", NULL); | |
+ if (reg) { | |
+ if (of_can_translate_address(np)) { | |
+ addr = of_translate_address(np, reg); | |
+ } else { | |
+ addrp = of_get_address(np, 0, NULL, NULL); | |
+ if (addrp) | |
+ addr = of_read_number(addrp, 1); | |
+ else | |
+ addr = OF_BAD_ADDR; | |
+ } | |
+ } | |
+ if (addr == OF_BAD_ADDR) { | |
+ pr_err("bcm2708: Could not determine device name for '%s'\n", np->full_name); | |
+ continue; | |
+ } | |
+ | |
+ if (of_property_read_u32(clkspec.np, "clock-frequency", &rate)) | |
+ continue; | |
+ | |
+ printk(" name=%s\n", np->name); | |
+ printk(" clock-frequency=%d\n", rate); | |
+ | |
+ lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); | |
+ dt_clk = kzalloc(sizeof(*dt_clk), GFP_KERNEL); | |
+ dev_id = kzalloc(32, GFP_KERNEL); | |
+ if (!lookup || !dt_clk || !dev_id) | |
+ return; | |
+ | |
+ scnprintf(dev_id, 32, "%llx.%s", (unsigned long long)addr, np->name); | |
+ | |
+ lookup->clk = dt_clk; | |
+ lookup->dev_id = dev_id; | |
+ dt_clk->rate = rate; | |
+ clkdev_add(lookup); | |
+ pr_info("bcm2708: added clock '%s', rate=%d\n", dev_id, rate); | |
+ } | |
+} | |
+ | |
+void __init bcm2708_dt_irq_init(void) | |
+{ | |
+ struct device_node *np; | |
+ struct irq_domain *domain; | |
+ | |
+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-armctrl-ic"); | |
+ if (!np) | |
+ return; | |
+ domain = irq_domain_add_legacy(np, MAXIRQNUM, IRQ_ARMCTRL_START, 0, | |
+ &irq_domain_simple_ops, NULL); | |
+ WARN_ON(!domain); | |
+} | |
+ | |
+static void __init bcm2708_dt_init(void) | |
+{ | |
+ struct device_node *np; | |
+ u32 linux_revision; | |
+ u64 linux_serial; | |
+ u32 clock_frequency; | |
+ | |
+ printk("bcm2708: %s()\n", __func__); | |
+ bcm2708_dt_clk_init(); | |
+ bcm2708_dt_irq_init(); | |
+ | |
+ np = of_find_node_by_path("/system"); | |
+ if (np) { | |
+ if (!of_property_read_u32(np, "linux,revision", &linux_revision)) | |
+ boardrev = linux_revision; | |
+ if (!of_property_read_u64(np, "linux,serial", &linux_serial)) | |
+ serial = (u32)linux_serial; | |
+ } | |
+ np = of_find_node_by_path("/axi/uart0"); | |
+ if (np && !of_property_read_u32(np, "clock-frequency", &clock_frequency)) | |
+ uart_clock = clock_frequency; | |
+} | |
+ | |
void __init bcm2708_init(void) | |
{ | |
int i; | |
+ bcm2708_dt_init(); | |
#if defined(CONFIG_BCM_VC_CMA) | |
vc_cma_early_init(); | |
#endif | |
@@ -732,7 +865,8 @@ void __init bcm2708_init(void) | |
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) | |
bcm_register_device(&bcm2708_alsa_devices[i]); | |
- bcm_register_device(&bcm2708_spi_device); | |
+// bcm_register_device(&bcm2708_spi_device); | |
bcm_register_device(&bcm2708_bsc0_device); | |
bcm_register_device(&bcm2708_bsc1_device); | |
@@ -745,11 +879,13 @@ void __init bcm2708_init(void) | |
} | |
system_rev = boardrev; | |
system_serial_low = serial; | |
- | |
+/* | |
#ifdef CONFIG_BCM2708_SPIDEV | |
spi_register_board_info(bcm2708_spi_devices, | |
ARRAY_SIZE(bcm2708_spi_devices)); | |
#endif | |
+*/ | |
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | |
} | |
static void timer_set_mode(enum clock_event_mode mode, | |
@@ -900,6 +1036,11 @@ static void __init board_reserve(void) | |
#endif | |
} | |
+static const char * const bcm2708_compat[] = { | |
+ "brcm,bcm2708", | |
+ NULL | |
+}; | |
+ | |
MACHINE_START(BCM2708, "BCM2708") | |
/* Maintainer: Broadcom Europe Ltd. */ | |
.map_io = bcm2708_map_io, | |
@@ -909,6 +1050,7 @@ MACHINE_START(BCM2708, "BCM2708") | |
.init_early = bcm2708_init_early, | |
.reserve = board_reserve, | |
.restart = bcm2708_restart, | |
+ .dt_compat = bcm2708_compat | |
MACHINE_END | |
module_param(boardrev, uint, 0644); | |
diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c | |
index 51d147a..2e45f6f 100644 | |
--- a/arch/arm/mach-bcm2708/dma.c | |
+++ b/arch/arm/mach-bcm2708/dma.c | |
@@ -13,6 +13,7 @@ | |
#include <linux/platform_device.h> | |
#include <linux/module.h> | |
#include <linux/scatterlist.h> | |
+#include <linux/of_device.h> | |
#include <mach/dma.h> | |
#include <mach/irqs.h> | |
@@ -281,6 +282,17 @@ static void dev_dmaman_deregister(const char *dev_name, struct device *dev) | |
static int dmachans = -1; /* module parameter */ | |
+static void bcm_dmaman_of_parse(void) | |
+{ | |
+ u32 channels; | |
+ struct device_node *np = of_find_node_by_path("/axi/dma"); | |
+ | |
+ if (np && !of_property_read_u32(np, "broadcom,channels", &channels)) { | |
+ printk(DRIVER_NAME ": /axi/dma/broadcom,channels = 0x%x\n", channels); | |
+ dmachans = channels; | |
+ } | |
+} | |
+ | |
static int bcm_dmaman_probe(struct platform_device *pdev) | |
{ | |
int ret = 0; | |
@@ -289,6 +301,8 @@ static int bcm_dmaman_probe(struct platform_device *pdev) | |
void __iomem *dma_base = NULL; | |
int have_dma_region = 0; | |
+ bcm_dmaman_of_parse(); | |
+ | |
dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); | |
if (NULL == dmaman) { | |
printk(KERN_ERR DRIVER_NAME ": failed to allocate " | |
diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c | |
index aeae4d5..3a43b08 100644 | |
--- a/arch/arm/mach-bcm2708/vc_mem.c | |
+++ b/arch/arm/mach-bcm2708/vc_mem.c | |
@@ -22,6 +22,7 @@ | |
#include <linux/proc_fs.h> | |
#include <asm/uaccess.h> | |
#include <linux/dma-mapping.h> | |
+#include <linux/of_device.h> | |
#ifdef CONFIG_ARCH_KONA | |
#include <chal/chal_ipc.h> | |
@@ -355,6 +356,19 @@ vc_mem_proc_write(struct file *file, const char __user * buffer, | |
* | |
***************************************************************************/ | |
+static void __init | |
+vc_mem_of_parse(void) | |
+{ | |
+ u32 reg[2]; | |
+ struct device_node *np = of_find_node_by_path("/axi/vc_mem"); | |
+ | |
+ if (np && !of_property_read_u32_array(np, "reg", reg, 2)) { | |
+ printk("/axi/vc_mem/reg = <0x%04X 0x%04X>\n", reg[0], reg[1]); | |
+ mem_base = reg[0]; | |
+ mem_size = reg[1]; | |
+ } | |
+} | |
+ | |
static int __init | |
vc_mem_init(void) | |
{ | |
@@ -363,6 +377,7 @@ vc_mem_init(void) | |
LOG_DBG("%s: called", __func__); | |
+ vc_mem_of_parse(); | |
mm_vc_mem_phys_addr = phys_addr; | |
mm_vc_mem_size = mem_size; | |
mm_vc_mem_base = mem_base; | |
arch/arm/boot/dts/bcm2708-rpi-b.dts | |
/dts-v1/; | |
/memreserve/ 0x1c000000 0x04000000; | |
/include/ "bcm2708.dtsi" | |
/ { | |
compatible = "brcm,bcm2708"; | |
model = "v31 Raspberry Pi Model B"; | |
memory { | |
reg = <0 0>; | |
}; | |
chosen { | |
bootargs = "earlyprintk loglevel=8 hello from dtb dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait"; | |
}; | |
system { | |
linux,serial = <0x00000000 0x00000000>; | |
linux,revision = <0x00000000>; | |
}; | |
display { | |
broadcom,width = <0x00000000>; | |
broadcom,height = <0x00000000>; | |
broadcom,depth = <0x00000000>; | |
}; | |
axi { | |
compatible = "simple-bus"; | |
#address-cells = <1>; | |
#size-cells = <1>; | |
vc_mem { | |
reg = <0x1ec00000 0x20000000>; | |
}; | |
usb { | |
hub { | |
ethernet { | |
mac-address = [00 00 00 00 00 00]; | |
}; | |
}; | |
}; | |
dma { | |
broadcom,channels = <0x00000000>; | |
}; | |
sdhci { | |
clock-frequency = <0x00000000>; | |
}; | |
uart0 { | |
clock-frequency = <0x00000000>; | |
}; | |
}; | |
aliases { | |
spi0 = &spi; | |
}; | |
}; | |
&spi { | |
status = "okay"; | |
spidev@0{ | |
#address-cells = <1>; | |
#size-cells = <0>; | |
compatible = "spidev"; | |
reg = <0>; | |
spi-max-frequency = <16000000>; | |
spi-cpha; | |
}; | |
spidev@1{ | |
#address-cells = <1>; | |
#size-cells = <0>; | |
compatible = "spidev"; | |
reg = <1>; | |
spi-max-frequency = <16000000>; | |
// Mode 0 (CPOL = 0, CPHA = 0) | |
}; | |
}; | |
arch/arm/boot/dts/bcm2708.dtsi | |
/include/ "skeleton.dtsi" | |
/ { | |
compatible = "brcm,bcm2708"; | |
model = "BCM2708"; | |
interrupt-parent = <&intc>; | |
chosen { | |
bootargs = "earlyprintk console=ttyAMA0"; | |
}; | |
axi { | |
compatible = "simple-bus"; | |
#address-cells = <1>; | |
#size-cells = <1>; | |
ranges = <0x7e000000 0x20000000 0x02000000>; | |
intc: interrupt-controller { | |
compatible = "brcm,bcm2835-armctrl-ic"; | |
reg = <0x7e00b200 0x200>; | |
interrupt-controller; | |
#interrupt-cells = <1>; | |
}; | |
spi: spi-bcm2708 { | |
compatible = "brcm,spi-bcm2708"; | |
#address-cells = <1>; | |
#size-cells = <0>; | |
reg = <0x7e204000 0x1000>; | |
interrupts = <80>; | |
clocks = <&clk_spi>; | |
status = "disabled"; | |
}; | |
}; | |
clocks { | |
compatible = "simple-bus"; | |
#address-cells = <1>; | |
#size-cells = <0>; | |
clk_spi: spi { | |
compatible = "fixed-clock"; | |
reg = <2>; | |
#clock-cells = <0>; | |
clock-frequency = <250000000>; | |
}; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment