diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-02-18 12:59:22 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-02-18 12:59:22 +0100 |
commit | e623cb9985d28451a6d21a157fa2e9e91f5bb377 (patch) | |
tree | b49191b306c3a30f43fca35f3275f976708ff190 /arch/arm | |
parent | cee0da03d33af0f1c0cf00b090db1890746eac80 (diff) | |
parent | 4ef6dbdba380dea39a73078b033ea58e66c0fbce (diff) | |
download | barebox-e623cb9985d28451a6d21a157fa2e9e91f5bb377.tar.gz barebox-e623cb9985d28451a6d21a157fa2e9e91f5bb377.tar.xz |
Merge branch 'for-next/rpi'
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boards/raspberry-pi/rpi-common.c | 486 | ||||
-rw-r--r-- | arch/arm/mach-bcm283x/mbox.c | 52 |
2 files changed, 308 insertions, 230 deletions
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c index 2684bd5ed7..9aa150de56 100644 --- a/arch/arm/boards/raspberry-pi/rpi-common.c +++ b/arch/arm/boards/raspberry-pi/rpi-common.c @@ -2,9 +2,11 @@ // SPDX-FileCopyrightText: 2009 Carlo Caione <carlo@carlocaione.org> #include <common.h> +#include <deep-probe.h> #include <init.h> #include <fs.h> #include <of.h> +#include <of_device.h> #include <linux/stat.h> #include <linux/clk.h> #include <linux/clkdev.h> @@ -28,16 +30,20 @@ #include "lowlevel.h" -struct rpi_model { - const char *name; - void (*init)(void); +struct rpi_priv; +struct rpi_machine_data { + int (*init)(struct rpi_priv *priv); + u8 hw_id; +#define RPI_OLD_SCHEMA BIT(0) + u8 flags; }; -#define RPI_MODEL(_id, _name, _init) \ - [_id] = { \ - .name = _name,\ - .init = _init,\ - } +struct rpi_priv { + struct device_d *dev; + const struct rpi_machine_data *dcfg; + unsigned int hw_id; + const char *name; +}; struct msg_get_arm_mem { struct bcm2835_mbox_hdr hdr; @@ -45,12 +51,6 @@ struct msg_get_arm_mem { u32 end_tag; }; -struct msg_get_clock_rate { - struct bcm2835_mbox_hdr hdr; - struct bcm2835_mbox_tag_get_clock_rate get_clock_rate; - u32 end_tag; -}; - struct msg_get_board_rev { struct bcm2835_mbox_hdr hdr; struct bcm2835_mbox_tag_get_board_rev get_board_rev; @@ -80,22 +80,6 @@ static int rpi_get_arm_mem(u32 *size) return 0; } -static struct clk *rpi_register_firmware_clock(u32 clock_id, const char *name) -{ - BCM2835_MBOX_STACK_ALIGN(struct msg_get_clock_rate, msg); - int ret; - - BCM2835_MBOX_INIT_HDR(msg); - BCM2835_MBOX_INIT_TAG(&msg->get_clock_rate, GET_CLOCK_RATE); - msg->get_clock_rate.body.req.clock_id = clock_id; - - ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); - if (ret) - return ERR_PTR(ret); - - return clk_fixed(name, msg->get_clock_rate.body.resp.rate_hz); -} - static void rpi_set_usbethaddr(void) { BCM2835_MBOX_STACK_ALIGN(struct msg_get_mac_address, msg); @@ -154,98 +138,56 @@ static void rpi_add_led(void) led_set_trigger(LED_TRIGGER_HEARTBEAT, &l->led); } -static void rpi_b_init(void) +static int rpi_b_init(struct rpi_priv *priv) { rpi_leds[0].gpio = 16; rpi_leds[0].active_low = 1; rpi_set_usbethaddr(); + + return 0; } -static void rpi_b_plus_init(void) +static int rpi_b_plus_init(struct rpi_priv *priv) { rpi_leds[0].gpio = 47; rpi_leds[1].gpio = 35; rpi_set_usbethaddr(); + + return 0; } -static void rpi_0_init(void) +static int rpi_0_init(struct rpi_priv *priv) { rpi_leds[0].gpio = 47; rpi_set_usbotg("usb0"); + + return 0; } -static void rpi_0_w_init(void) +static int rpi_0_w_init(struct rpi_priv *priv) { struct device_node *np; int ret; - rpi_0_init(); + rpi_0_init(priv); np = of_find_node_by_path("/chosen"); if (!np) - return; + return -ENODEV; if (!of_device_enable_and_register_by_alias("serial1")) - return; + return -ENODEV; ret = of_property_write_string(np, "stdout-path", "serial1:115200n8"); if (ret) - return; + return ret; - of_device_disable_by_alias("serial0"); + return of_device_disable_by_alias("serial0"); } -/* See comments in mbox.h for data source */ -static const struct rpi_model rpi_models_old_scheme[] = { - RPI_MODEL(0, "Unknown model", NULL), - RPI_MODEL(BCM2835_BOARD_REV_B_I2C0_2, "Model B (no P5)", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_I2C0_3, "Model B (no P5)", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_I2C1_4, "Model B", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_I2C1_5, "Model B", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_I2C1_6, "Model B", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_A_7, "Model A", NULL), - RPI_MODEL(BCM2835_BOARD_REV_A_8, "Model A", NULL), - RPI_MODEL(BCM2835_BOARD_REV_A_9, "Model A", NULL), - RPI_MODEL(BCM2835_BOARD_REV_B_REV2_d, "Model B rev2", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_REV2_e, "Model B rev2", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_REV2_f, "Model B rev2", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_PLUS_10, "Model B+", rpi_b_plus_init), - RPI_MODEL(BCM2835_BOARD_REV_CM_11, "Compute Module", NULL), - RPI_MODEL(BCM2835_BOARD_REV_A_PLUS_12, "Model A+", NULL), - RPI_MODEL(BCM2835_BOARD_REV_B_PLUS_13, "Model B+", rpi_b_plus_init), - RPI_MODEL(BCM2835_BOARD_REV_CM_14, "Compute Module", NULL), - RPI_MODEL(BCM2835_BOARD_REV_A_PLUS_15, "Model A+", NULL), -}; - -static const struct rpi_model rpi_models_new_scheme[] = { - RPI_MODEL(BCM2835_BOARD_REV_A, "Model A", NULL ), - RPI_MODEL(BCM2835_BOARD_REV_B, "Model B", rpi_b_init ), - RPI_MODEL(BCM2835_BOARD_REV_A_PLUS, "Model A+", NULL ), - RPI_MODEL(BCM2835_BOARD_REV_B_PLUS, "Model B+", rpi_b_plus_init ), - RPI_MODEL(BCM2836_BOARD_REV_2_B, "Model 2B", rpi_b_plus_init), - RPI_MODEL(BCM283x_BOARD_REV_Alpha, "Alpha", NULL), - RPI_MODEL(BCM2835_BOARD_REV_CM1, "Compute Module", NULL ), - RPI_MODEL(0x7, "Unknown model", NULL), - RPI_MODEL(BCM2837_BOARD_REV_3_B, "Model 3B", rpi_b_init ), - RPI_MODEL(BCM2835_BOARD_REV_ZERO, "Zero", rpi_0_init), - RPI_MODEL(BCM2837_BOARD_REV_CM3, "Compute Module 3", NULL ), - RPI_MODEL(0xb, "Unknown model", NULL), - RPI_MODEL(BCM2835_BOARD_REV_ZERO_W, "Zero W", rpi_0_w_init), - RPI_MODEL(BCM2837B0_BOARD_REV_3B_PLUS, "Model 3B+", rpi_b_plus_init ), - RPI_MODEL(BCM2837B0_BOARD_REV_3A_PLUS, "Model 3A+", rpi_b_plus_init), - RPI_MODEL(0xf, "Unknown model", NULL), - RPI_MODEL(BCM2837B0_BOARD_REV_CM3_PLUS, "Compute Module 3+", NULL), -}; - -static int rpi_board_rev = 0; -static const struct rpi_model *model = NULL; - -static void rpi_get_board_rev(void) +static int rpi_get_board_rev(struct rpi_priv *priv) { int ret; - char *name; - const struct rpi_model *rpi_models; - size_t rpi_models_size; BCM2835_MBOX_STACK_ALIGN(struct msg_get_board_rev, msg); BCM2835_MBOX_INIT_HDR(msg); @@ -253,9 +195,8 @@ static void rpi_get_board_rev(void) ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); if (ret) { - printf("bcm2835: Could not query board revision\n"); - /* Ignore error; not critical */ - return; + dev_err(priv->dev, "Could not query board revision\n"); + return ret; } /* Comments from u-boot: @@ -269,53 +210,9 @@ static void rpi_get_board_rev(void) * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250 * http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594 */ - rpi_board_rev = msg->get_board_rev.body.resp.rev; - if (rpi_board_rev & 0x800000) { - rpi_board_rev = (rpi_board_rev >> 4) & 0xff; - rpi_models = rpi_models_new_scheme; - rpi_models_size = ARRAY_SIZE(rpi_models_new_scheme); - - } else { - rpi_board_rev &= 0xff; - rpi_models = rpi_models_old_scheme; - rpi_models_size = ARRAY_SIZE(rpi_models_old_scheme); - } - - if (rpi_board_rev >= rpi_models_size) { - printf("RPI: Board rev %u outside known range\n", - rpi_board_rev); - goto unknown_rev; - } - - if (!rpi_models[rpi_board_rev].name) { - printf("RPI: Board rev %u unknown\n", rpi_board_rev); - goto unknown_rev; - } - - if (!rpi_board_rev) - goto unknown_rev; - - model = &rpi_models[rpi_board_rev]; - name = basprintf("RaspberryPi %s", model->name); - barebox_set_model(name); - free(name); - - return; + priv->hw_id = msg->get_board_rev.body.resp.rev; -unknown_rev: - rpi_board_rev = 0; - barebox_set_model("RaspberryPi (unknown rev)"); -} - -static void rpi_model_init(void) -{ - if (!model) - return; - - if (!model->init) - return; - - model->init(); + return 0; } static int rpi_mem_init(void) @@ -333,67 +230,6 @@ static int rpi_mem_init(void) } mem_initcall(rpi_mem_init); -static int rpi_postcore_init(void) -{ - rpi_get_board_rev(); - barebox_set_hostname("rpi"); - rpi_model_init(); - - return 0; -} -postcore_initcall(rpi_postcore_init); - -static int rpi_clock_init(void) -{ - struct clk *clk; - - clk = rpi_register_firmware_clock(BCM2835_MBOX_CLOCK_ID_EMMC, - "bcm2835_mci0"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - clkdev_add_physbase(clk, 0x20300000, NULL); - clkdev_add_physbase(clk, 0x3f300000, NULL); - - clk = rpi_register_firmware_clock(BCM2835_MBOX_CLOCK_ID_CORE, - "bcm2835_sdhost"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - clkdev_add_physbase(clk, 0x20202000, NULL); - clkdev_add_physbase(clk, 0x3f202000, NULL); - - return 0; -} -postconsole_initcall(rpi_clock_init); - -static int rpi_console_clock_init(void) -{ - struct clk *clk; - - clk = clk_fixed("apb_pclk", 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - - clk = clk_fixed("uart0-pl0110", 48 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "uart0-pl0110"); - clkdev_add_physbase(clk, BCM2835_PL011_BASE, NULL); - clkdev_add_physbase(clk, BCM2836_PL011_BASE, NULL); - - clk = rpi_register_firmware_clock(BCM2835_MBOX_CLOCK_ID_CORE, - "uart1-8250"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - clkdev_add_physbase(clk, BCM2835_MINIUART_BASE, NULL); - clkdev_add_physbase(clk, BCM2836_MINIUART_BASE, NULL); - - clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "bcm2835-cs"); - - return 0; -} -postcore_initcall(rpi_console_clock_init); - static int rpi_env_init(void) { struct stat s; @@ -511,9 +347,59 @@ static void rpi_vc_fdt(void) } } -static int rpi_devices_init(void) +static const struct rpi_machine_data *rpi_get_dcfg(struct rpi_priv *priv) { + const struct rpi_machine_data *dcfg; + + dcfg = of_device_get_match_data(priv->dev); + if (!dcfg) + return ERR_PTR(-EINVAL); + + for (; dcfg->hw_id != U8_MAX; dcfg++) { + if (priv->hw_id & 0x800000) { + if (dcfg->hw_id != ((priv->hw_id >> 4) & 0xff)) + continue; + } else { + if (!(dcfg->flags & RPI_OLD_SCHEMA)) + continue; + if (dcfg->hw_id != (priv->hw_id & 0xff)) + continue; + } + + return dcfg; + } + + dev_err(priv->dev, "Failed to get dcfg for board_id: 0x%x.\n", + priv->hw_id); + return ERR_PTR(-ENODEV); +} + +static int rpi_devices_probe(struct device_d *dev) +{ + const struct rpi_machine_data *dcfg; struct regulator *reg; + struct rpi_priv *priv; + const char *name, *ptr; + char *hostname; + int ret; + + priv = xzalloc(sizeof(*priv)); + priv->dev = dev; + + ret = rpi_get_board_rev(priv); + if (ret) + goto free_priv; + + dcfg = rpi_get_dcfg(priv); + if (IS_ERR(dcfg)) + goto free_priv; + + /* construct short recognizable host name */ + name = of_device_get_match_compatible(priv->dev); + ptr = strchr(name, ','); + hostname = basprintf("rpi-%s", ptr ? ptr + 1 : name); + barebox_set_hostname(hostname); + free(hostname); rpi_add_led(); bcm2835_register_fb(); @@ -521,6 +407,9 @@ static int rpi_devices_init(void) rpi_env_init(); rpi_vc_fdt(); + if (dcfg->init) + dcfg->init(priv); + reg = regulator_get_name("bcm2835_usb"); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -528,5 +417,202 @@ static int rpi_devices_init(void) regulator_enable(reg); return 0; + +free_priv: + kfree(priv); + return ret; } -late_initcall(rpi_devices_init); + +static const struct rpi_machine_data rpi_model_a[] = { + { + .hw_id = BCM2835_BOARD_REV_A_7, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_A_8, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_A_9, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_A, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_a_plus[] = { + { + .hw_id = BCM2835_BOARD_REV_A_PLUS_12, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_A_PLUS_15, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_A_PLUS, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_b[] = { + { + .hw_id = BCM2835_BOARD_REV_B_I2C1_4, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_B_I2C1_5, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_B_I2C1_6, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_B, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_b_i2c0[] = { + { + .hw_id = BCM2835_BOARD_REV_B_I2C0_2, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_B_I2C0_3, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_b_rev2[] = { + { + .hw_id = BCM2835_BOARD_REV_B_REV2_d, + .flags = RPI_OLD_SCHEMA, + .init = rpi_b_init, + }, { + .hw_id = BCM2835_BOARD_REV_B_REV2_e, + .flags = RPI_OLD_SCHEMA, + .init = rpi_b_init, + }, { + .hw_id = BCM2835_BOARD_REV_B_REV2_f, + .flags = RPI_OLD_SCHEMA, + .init = rpi_b_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_b_plus[] = { + { + .hw_id = BCM2835_BOARD_REV_B_PLUS_10, + .flags = RPI_OLD_SCHEMA, + .init = rpi_b_plus_init, + }, { + .hw_id = BCM2835_BOARD_REV_B_PLUS_13, + .flags = RPI_OLD_SCHEMA, + .init = rpi_b_plus_init, + }, { + .hw_id = BCM2835_BOARD_REV_B_PLUS, + .init = rpi_b_plus_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_compute_module[] = { + { + .hw_id = BCM2835_BOARD_REV_CM_11, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_CM_14, + .flags = RPI_OLD_SCHEMA, + }, { + .hw_id = BCM2835_BOARD_REV_CM1, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_zero[] = { + { + .hw_id = BCM2835_BOARD_REV_ZERO, + .init = rpi_0_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_model_zero_w[] = { + { + .hw_id = BCM2835_BOARD_REV_ZERO_W, + .init = rpi_0_w_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_2_model_b[] = { + { + .hw_id = BCM2836_BOARD_REV_2_B, + .init = rpi_b_plus_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_3_model_a_plus[] = { + { + .hw_id = BCM2837B0_BOARD_REV_3A_PLUS, + .init = rpi_b_plus_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_3_model_b[] = { + { + .hw_id = BCM2837_BOARD_REV_3_B, + .init = rpi_b_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct rpi_machine_data rpi_3_model_b_plus[] = { + { + .hw_id = BCM2837B0_BOARD_REV_3B_PLUS, + .init = rpi_b_plus_init, + }, { + .hw_id = U8_MAX + }, +}; + +static const struct of_device_id rpi_of_match[] = { + /* BCM2835 based Boards */ + { .compatible = "raspberrypi,model-a", .data = rpi_model_a }, + { .compatible = "raspberrypi,model-a-plus", .data = rpi_model_a_plus }, + { .compatible = "raspberrypi,model-b", .data = rpi_model_b }, + /* Raspberry Pi Model B (no P5) */ + { .compatible = "raspberrypi,model-b-i2c0", .data = rpi_model_b_i2c0 }, + { .compatible = "raspberrypi,model-b-rev2", .data = rpi_model_b_rev2 }, + { .compatible = "raspberrypi,model-b-plus", .data = rpi_model_b_plus }, + { .compatible = "raspberrypi,compute-module", .data = rpi_compute_module }, + { .compatible = "raspberrypi,model-zero", .data = rpi_model_zero }, + { .compatible = "raspberrypi,model-zero-w", .data = rpi_model_zero_w }, + + /* BCM2836 based Boards */ + { .compatible = "raspberrypi,2-model-b", .data = rpi_2_model_b }, + + /* BCM2837 based Boards */ + { .compatible = "raspberrypi,3-model-a-plus", .data = rpi_3_model_a_plus }, + { .compatible = "raspberrypi,3-model-b", .data = rpi_3_model_b }, + { .compatible = "raspberrypi,3-model-b-plus", .data = rpi_3_model_b_plus }, + { /* sentinel */ }, +}; +BAREBOX_DEEP_PROBE_ENABLE(rpi_of_match); + +static struct driver_d rpi_board_driver = { + .name = "board-rpi", + .probe = rpi_devices_probe, + .of_compatible = DRV_OF_COMPAT(rpi_of_match), +}; +late_platform_driver(rpi_board_driver); diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c index 9839683d03..4b14afcfe4 100644 --- a/arch/arm/mach-bcm283x/mbox.c +++ b/arch/arm/mach-bcm283x/mbox.c @@ -13,6 +13,7 @@ #include <dma.h> #include <init.h> #include <io.h> +#include <of_address.h> #include <mach/mbox.h> @@ -108,6 +109,21 @@ static void dump_buf(struct bcm2835_mbox_hdr *buffer) } #endif +static int bcm2835_mbox_probe(void) +{ + struct device_node *mbox_node; + + mbox_node = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-mbox"); + if (!mbox_node) { + pr_err("Missing mbox node\n"); + return -ENOENT; + } + + mbox_base = of_iomap(mbox_node, 0); + + return 0; +} + int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer) { int ret; @@ -115,6 +131,12 @@ int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer) struct bcm2835_mbox_tag_hdr *tag; int tag_index; + if (!mbox_base) { + ret = bcm2835_mbox_probe(); + if (ret) + return ret; + } + pr_debug("mbox: TX buffer\n"); dump_buf(buffer); @@ -150,33 +172,3 @@ int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer) return 0; } - -static int bcm2835_mbox_probe(struct device_d *dev) -{ - struct resource *iores; - - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) { - dev_err(dev, "could not get memory region\n"); - return PTR_ERR(iores); - } - mbox_base = IOMEM(iores->start); - - return 0; -} - -static __maybe_unused struct of_device_id bcm2835_mbox_dt_ids[] = { - { - .compatible = "brcm,bcm2835-mbox", - }, { - /* sentinel */ - }, -}; - -static struct driver_d bcm2835_mbox_driver = { - .name = "bcm2835_mbox", - .of_compatible = DRV_OF_COMPAT(bcm2835_mbox_dt_ids), - .probe = bcm2835_mbox_probe, -}; - -core_platform_driver(bcm2835_mbox_driver); |