summaryrefslogtreecommitdiff
authorShunzhou Jiang <shunzhou.jiang@amlogic.com>2019-08-20 12:09:13 (GMT)
committer Tao Zeng <tao.zeng@amlogic.com>2019-09-12 08:22:02 (GMT)
commit5412b149136e49f05dd860a8a464471a80099383 (patch)
tree97df5677c44492cbb80fc3f2e45c41d09284b5f8
parentb2ac7eef331478496373bee3e585471607a062ef (diff)
downloadcommon-5412b149136e49f05dd860a8a464471a80099383.zip
common-5412b149136e49f05dd860a8a464471a80099383.tar.gz
common-5412b149136e49f05dd860a8a464471a80099383.tar.bz2
bl40: g12a/sm1: add m4 bringup path [1/3]
PD#SWPL-12964 Problem: bring up m4 Solution: add kernel driver Verify: U209+S905D3 Change-Id: Iaa57f24c919af013581b8e3faffb0b57f5af10ed Signed-off-by: Shunzhou Jiang <shunzhou.jiang@amlogic.com>
Diffstat
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/boot/dts/amlogic/mesong12a.dtsi5
-rw-r--r--arch/arm/boot/dts/amlogic/mesonsm1.dtsi5
-rw-r--r--arch/arm/configs/meson64_a32_defconfig1
-rw-r--r--arch/arm64/boot/dts/amlogic/mesong12a.dtsi5
-rw-r--r--arch/arm64/boot/dts/amlogic/mesonsm1.dtsi5
-rw-r--r--arch/arm64/configs/meson64_defconfig1
-rw-r--r--drivers/amlogic/Kconfig2
-rw-r--r--drivers/amlogic/Makefile2
-rw-r--r--drivers/amlogic/firmware/Kconfig11
-rw-r--r--drivers/amlogic/firmware/Makefile2
-rw-r--r--drivers/amlogic/firmware/bl40_module.c159
-rw-r--r--drivers/amlogic/mailbox/scpi_protocol.c18
-rw-r--r--include/linux/amlogic/scpi_protocol.h2
14 files changed, 224 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 1708ee9..9fc6c2a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15147,3 +15147,9 @@ F: include/dt-bindings/display/meson-drm-ids.h
AMLOGIC LCD EXTERN DRIVER
M: Shaochan Liu <shaochan.liu@amlogic.com>
F: drivers/amlogic/media/vout/lcd/lcd_extern/i2c_CS602.c
+
+AMLOGIC SM1/G12A BL40 BOOTUP DRIVER
+M: shunzhou jiang <shunzhou.jiang@amlogic.com>
+F: drivers/amlogic/firmware/bl40_module.c
+F: drivers/amlogic/firmware/Makefile
+F: drivers/amlogic/firmware/Kconfig
diff --git a/arch/arm/boot/dts/amlogic/mesong12a.dtsi b/arch/arm/boot/dts/amlogic/mesong12a.dtsi
index 47b5d2f..806e3b8 100644
--- a/arch/arm/boot/dts/amlogic/mesong12a.dtsi
+++ b/arch/arm/boot/dts/amlogic/mesong12a.dtsi
@@ -503,6 +503,11 @@
#thermal-sensor-cells = <1>;
};
+ bl40: bl40 {
+ compatible = "amlogic, bl40-bootup";
+ status = "okay";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
index 16ba4a2..341060f 100644
--- a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
+++ b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi
@@ -501,6 +501,11 @@
<0xff63c100 0x10>;
};
+ bl40: bl40 {
+ compatible = "amlogic, bl40-bootup";
+ status = "okay";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/configs/meson64_a32_defconfig b/arch/arm/configs/meson64_a32_defconfig
index 9f925b7..15b533d 100644
--- a/arch/arm/configs/meson64_a32_defconfig
+++ b/arch/arm/configs/meson64_a32_defconfig
@@ -386,6 +386,7 @@ CONFIG_AMLOGIC_BATTERY_DUMMY=y
CONFIG_AMLOGIC_CHARGER_DUMMY=y
CONFIG_AMLOGIC_HIFI4DSP=y
CONFIG_AMLOGIC_PIXEL_PROBE=y
+CONFIG_AMLOGIC_FIRMWARE=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
index 0bf23d3..b657453 100644
--- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
+++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi
@@ -503,6 +503,11 @@
#thermal-sensor-cells = <1>;
};
+ bl40: bl40 {
+ compatible = "amlogic, bl40-bootup";
+ status = "okay";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
diff --git a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
index ac87f8a..fb1ccb6 100644
--- a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi
@@ -501,6 +501,11 @@
<0x0 0xff63c100 0x0 0x10>;
};
+ bl40: bl40 {
+ compatible = "amlogic, bl40-bootup";
+ status = "okay";
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig
index 79a0cc2..7d4ff94 100644
--- a/arch/arm64/configs/meson64_defconfig
+++ b/arch/arm64/configs/meson64_defconfig
@@ -382,6 +382,7 @@ CONFIG_AMLOGIC_CHARGER_DUMMY=y
CONFIG_DOLBY_FW=y
CONFIG_AMLOGIC_HIFI4DSP=y
CONFIG_AMLOGIC_PIXEL_PROBE=y
+CONFIG_AMLOGIC_FIRMWARE=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
diff --git a/drivers/amlogic/Kconfig b/drivers/amlogic/Kconfig
index 32493b0..93ee0eb 100644
--- a/drivers/amlogic/Kconfig
+++ b/drivers/amlogic/Kconfig
@@ -144,5 +144,7 @@ source "drivers/amlogic/hifi4dsp/Kconfig"
source "drivers/amlogic/pixel_probe/Kconfig"
+source "drivers/amlogic/firmware/Kconfig"
+
endmenu
endif
diff --git a/drivers/amlogic/Makefile b/drivers/amlogic/Makefile
index 885097b..5ed5331 100644
--- a/drivers/amlogic/Makefile
+++ b/drivers/amlogic/Makefile
@@ -141,3 +141,5 @@ obj-$(CONFIG_DOLBY_FW) += dolby_fw/
obj-$(CONFIG_AMLOGIC_IRCUT) += ircut/
obj-$(CONFIG_AMLOGIC_PIXEL_PROBE) += pixel_probe/
+
+obj-$(CONFIG_AMLOGIC_FIRMWARE) += firmware/
diff --git a/drivers/amlogic/firmware/Kconfig b/drivers/amlogic/firmware/Kconfig
new file mode 100644
index 0000000..89d6645
--- a/dev/null
+++ b/drivers/amlogic/firmware/Kconfig
@@ -0,0 +1,11 @@
+# firmware configuration
+#
+menu "AMLOGIC firmware boot"
+
+config AMLOGIC_FIRMWARE
+ bool "firmware bootup support"
+ default n
+ help
+ support the amlogic firmware bootup;
+
+endmenu
diff --git a/drivers/amlogic/firmware/Makefile b/drivers/amlogic/firmware/Makefile
new file mode 100644
index 0000000..e33ea26
--- a/dev/null
+++ b/drivers/amlogic/firmware/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_AMLOGIC_FIRMWARE) += bl40_module.o
diff --git a/drivers/amlogic/firmware/bl40_module.c b/drivers/amlogic/firmware/bl40_module.c
new file mode 100644
index 0000000..e7436a6
--- a/dev/null
+++ b/drivers/amlogic/firmware/bl40_module.c
@@ -0,0 +1,159 @@
+/*
+ * drivers/amlogic/firmware/bl40_module.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) "bl40: " fmt
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/reset.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <asm/cacheflush.h>
+#include <linux/firmware.h>
+#include <linux/arm-smccc.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/amlogic/scpi_protocol.h>
+
+#define AMLOGIC_BL40_BOOTUP 0x8200004E
+struct bl40_info {
+ char name[30];
+};
+
+struct device *device;
+#define BL40_IOC_MAGIC 'H'
+#define BL40_FIRMWARE_LOAD _IOWR(BL40_IOC_MAGIC, 1, struct bl40_info)
+
+static long bl40_miscdev_ioctl(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+ const struct firmware *firmware;
+ void __user *argp = (void __user *)arg;
+ struct bl40_info bl40_info;
+ unsigned long phy_addr;
+ void *virt_addr = NULL;
+ struct arm_smccc_res res = {0};
+ size_t size;
+
+ switch (cmd) {
+ case BL40_FIRMWARE_LOAD:
+ ret = copy_from_user((void *)&bl40_info,
+ argp, sizeof(bl40_info));
+ if (ret < 0)
+ return ret;
+ ret = request_firmware(&firmware, bl40_info.name, device);
+ if (ret < 0) {
+ pr_err("req firmware fail %d\n", ret);
+ return ret;
+ }
+
+ size = firmware->size;
+ virt_addr = devm_kzalloc(device, size, GFP_KERNEL);
+ if (!virt_addr) {
+ release_firmware(firmware);
+ pr_err("memory request fail\n");
+ return -ENOMEM;
+ }
+ memcpy(virt_addr, firmware->data, size);
+ release_firmware(firmware);
+ dma_map_single(device, virt_addr, size, DMA_FROM_DEVICE);
+ phy_addr = virt_to_phys(virt_addr);
+
+ /* unlock bl40 */
+ scpi_unlock_bl40();
+ arm_smccc_smc(AMLOGIC_BL40_BOOTUP, phy_addr,
+ size, 0, 0, 0, 0, 0, &res);
+ pr_info("free memory\n");
+ devm_kfree(device, virt_addr);
+ ret = res.a0;
+ break;
+ default:
+ pr_info("Not have this cmd\n");
+ break;
+ };
+ pr_info("bl40 ioctl\n");
+ return ret;
+}
+
+static const struct file_operations bl40_miscdev_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .unlocked_ioctl = bl40_miscdev_ioctl,
+ .compat_ioctl = bl40_miscdev_ioctl,
+};
+
+static struct miscdevice bl40_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "bl40",
+ .fops = &bl40_miscdev_fops,
+};
+
+static int bl40_platform_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ device = &pdev->dev;
+ platform_set_drvdata(pdev, NULL);
+ ret = misc_register(&bl40_miscdev);
+ pr_info("bl40 probe\n");
+ return ret;
+}
+
+static int bl40_platform_remove(struct platform_device *pdev)
+{
+ misc_deregister(&bl40_miscdev);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static const struct of_device_id bl40_device_id[] = {
+ {
+ .compatible = "amlogic, bl40-bootup",
+ },
+ {}
+};
+
+static struct platform_driver bl40_platform_driver = {
+ .driver = {
+ .name = "bl40",
+ .owner = THIS_MODULE,
+ .of_match_table = bl40_device_id,
+ },
+ .probe = bl40_platform_probe,
+ .remove = bl40_platform_remove,
+};
+module_platform_driver(bl40_platform_driver);
+
+MODULE_AUTHOR("Amlogic Bl40");
+MODULE_DESCRIPTION("BL40 Boot Module Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/amlogic/mailbox/scpi_protocol.c b/drivers/amlogic/mailbox/scpi_protocol.c
index 7718892..7158f3f 100644
--- a/drivers/amlogic/mailbox/scpi_protocol.c
+++ b/drivers/amlogic/mailbox/scpi_protocol.c
@@ -671,3 +671,21 @@ int scpi_get_cpuinfo(enum scpi_get_pfm_type type, u32 *freq, u32 *vol)
return ret;
}
EXPORT_SYMBOL_GPL(scpi_get_cpuinfo);
+
+int scpi_unlock_bl40(void)
+{
+ struct scpi_data_buf sdata;
+ struct mhu_data_buf mdata;
+ u8 temp = 0;
+
+ struct __packed {
+ u32 status;
+ } buf;
+
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_NONE,
+ SCPI_CMD_BL4_WAIT_UNLOCK, temp, buf);
+ if (scpi_execute_cmd(&sdata))
+ return -1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(scpi_unlock_bl40);
diff --git a/include/linux/amlogic/scpi_protocol.h b/include/linux/amlogic/scpi_protocol.h
index 06c829d..b433f59 100644
--- a/include/linux/amlogic/scpi_protocol.h
+++ b/include/linux/amlogic/scpi_protocol.h
@@ -73,6 +73,7 @@ enum scpi_std_cmd {
SCPI_CMD_GET_CEC1 = 0xB4,
SCPI_CMD_GET_CEC2 = 0xB5,
+ SCPI_CMD_BL4_WAIT_UNLOCK = 0xD6,
SCPI_CMD_COUNT
};
@@ -112,4 +113,5 @@ int scpi_get_cec_val(enum scpi_std_cmd index, u32 *p_cec);
u8 scpi_get_ethernet_calc(void);
int scpi_get_cpuinfo(enum scpi_get_pfm_type type, u32 *freq, u32 *vol);
int scpi_init_dsp_cfg0(u32 id, u32 addr, u32 cfg0);
+int scpi_unlock_bl40(void);
#endif /*_SCPI_PROTOCOL_H_*/