Skip to content

Instantly share code, notes, and snippets.

@notro
Last active December 25, 2015 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notro/6903349 to your computer and use it in GitHub Desktop.
Save notro/6903349 to your computer and use it in GitHub Desktop.
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