|
@@ -38,9 +38,6 @@
|
|
|
#include <mach/db8500-regs.h>
|
|
|
#include "dbx500-prcmu-regs.h"
|
|
|
|
|
|
-/* Offset for the firmware version within the TCPM */
|
|
|
-#define PRCMU_FW_VERSION_OFFSET 0xA4
|
|
|
-
|
|
|
/* Index of different voltages to be used when accessing AVSData */
|
|
|
#define PRCM_AVS_BASE 0x2FC
|
|
|
#define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0)
|
|
@@ -2704,21 +2701,43 @@ static struct irq_chip prcmu_irq_chip = {
|
|
|
.irq_unmask = prcmu_irq_unmask,
|
|
|
};
|
|
|
|
|
|
-static char *fw_project_name(u8 project)
|
|
|
+static __init char *fw_project_name(u32 project)
|
|
|
{
|
|
|
switch (project) {
|
|
|
case PRCMU_FW_PROJECT_U8500:
|
|
|
return "U8500";
|
|
|
- case PRCMU_FW_PROJECT_U8500_C2:
|
|
|
- return "U8500 C2";
|
|
|
+ case PRCMU_FW_PROJECT_U8400:
|
|
|
+ return "U8400";
|
|
|
case PRCMU_FW_PROJECT_U9500:
|
|
|
return "U9500";
|
|
|
- case PRCMU_FW_PROJECT_U9500_C2:
|
|
|
- return "U9500 C2";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_MBB:
|
|
|
+ return "U8500 MBB";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_C1:
|
|
|
+ return "U8500 C1";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_C2:
|
|
|
+ return "U8500 C2";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_C3:
|
|
|
+ return "U8500 C3";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_C4:
|
|
|
+ return "U8500 C4";
|
|
|
+ case PRCMU_FW_PROJECT_U9500_MBL:
|
|
|
+ return "U9500 MBL";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_MBL:
|
|
|
+ return "U8500 MBL";
|
|
|
+ case PRCMU_FW_PROJECT_U8500_MBL2:
|
|
|
+ return "U8500 MBL2";
|
|
|
case PRCMU_FW_PROJECT_U8520:
|
|
|
- return "U8520";
|
|
|
+ return "U8520 MBL";
|
|
|
case PRCMU_FW_PROJECT_U8420:
|
|
|
return "U8420";
|
|
|
+ case PRCMU_FW_PROJECT_U9540:
|
|
|
+ return "U9540";
|
|
|
+ case PRCMU_FW_PROJECT_A9420:
|
|
|
+ return "A9420";
|
|
|
+ case PRCMU_FW_PROJECT_L8540:
|
|
|
+ return "L8540";
|
|
|
+ case PRCMU_FW_PROJECT_L8580:
|
|
|
+ return "L8580";
|
|
|
default:
|
|
|
return "Unknown";
|
|
|
}
|
|
@@ -2764,37 +2783,44 @@ static int db8500_irq_init(struct device_node *np)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-void __init db8500_prcmu_early_init(void)
|
|
|
+static void dbx500_fw_version_init(struct platform_device *pdev,
|
|
|
+ u32 version_offset)
|
|
|
{
|
|
|
- if (cpu_is_u8500v2() || cpu_is_u9540()) {
|
|
|
- void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
|
|
|
-
|
|
|
- if (tcpm_base != NULL) {
|
|
|
- u32 version;
|
|
|
- version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET);
|
|
|
- fw_info.version.project = version & 0xFF;
|
|
|
- fw_info.version.api_version = (version >> 8) & 0xFF;
|
|
|
- fw_info.version.func_version = (version >> 16) & 0xFF;
|
|
|
- fw_info.version.errata = (version >> 24) & 0xFF;
|
|
|
- fw_info.valid = true;
|
|
|
- pr_info("PRCMU firmware: %s, version %d.%d.%d\n",
|
|
|
- fw_project_name(fw_info.version.project),
|
|
|
- (version >> 8) & 0xFF, (version >> 16) & 0xFF,
|
|
|
- (version >> 24) & 0xFF);
|
|
|
- iounmap(tcpm_base);
|
|
|
- }
|
|
|
+ struct resource *res;
|
|
|
+ void __iomem *tcpm_base;
|
|
|
|
|
|
- if (cpu_is_u9540())
|
|
|
- tcdm_base = ioremap_nocache(U8500_PRCMU_TCDM_BASE,
|
|
|
- SZ_4K + SZ_8K) + SZ_8K;
|
|
|
- else
|
|
|
- tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
|
|
|
- } else {
|
|
|
- pr_err("prcmu: Unsupported chip version\n");
|
|
|
- BUG();
|
|
|
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
|
|
+ "prcmu-tcpm");
|
|
|
+ if (!res) {
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "Error: no prcmu tcpm memory region provided\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ tcpm_base = ioremap(res->start, resource_size(res));
|
|
|
+ if (tcpm_base != NULL) {
|
|
|
+ u32 version;
|
|
|
+
|
|
|
+ version = readl(tcpm_base + version_offset);
|
|
|
+ fw_info.version.project = (version & 0xFF);
|
|
|
+ fw_info.version.api_version = (version >> 8) & 0xFF;
|
|
|
+ fw_info.version.func_version = (version >> 16) & 0xFF;
|
|
|
+ fw_info.version.errata = (version >> 24) & 0xFF;
|
|
|
+ strncpy(fw_info.version.project_name,
|
|
|
+ fw_project_name(fw_info.version.project),
|
|
|
+ PRCMU_FW_PROJECT_NAME_LEN);
|
|
|
+ fw_info.valid = true;
|
|
|
+ pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n",
|
|
|
+ fw_info.version.project_name,
|
|
|
+ fw_info.version.project,
|
|
|
+ fw_info.version.api_version,
|
|
|
+ fw_info.version.func_version,
|
|
|
+ fw_info.version.errata);
|
|
|
+ iounmap(tcpm_base);
|
|
|
}
|
|
|
- tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
|
|
|
+}
|
|
|
|
|
|
+void __init db8500_prcmu_early_init(void)
|
|
|
+{
|
|
|
spin_lock_init(&mb0_transfer.lock);
|
|
|
spin_lock_init(&mb0_transfer.dbb_irqs_lock);
|
|
|
mutex_init(&mb0_transfer.ac_wake_lock);
|
|
@@ -3104,20 +3130,30 @@ static void db8500_prcmu_update_cpufreq(void)
|
|
|
*/
|
|
|
static int db8500_prcmu_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
- struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data;
|
|
|
struct device_node *np = pdev->dev.of_node;
|
|
|
+ struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev);
|
|
|
int irq = 0, err = 0, i;
|
|
|
+ struct resource *res;
|
|
|
|
|
|
init_prcm_registers();
|
|
|
|
|
|
+ dbx500_fw_version_init(pdev, pdata->version_offset);
|
|
|
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");
|
|
|
+ if (!res) {
|
|
|
+ dev_err(&pdev->dev, "no prcmu tcdm region provided\n");
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+ tcdm_base = devm_ioremap(&pdev->dev, res->start,
|
|
|
+ resource_size(res));
|
|
|
+
|
|
|
/* Clean up the mailbox interrupts after pre-kernel code. */
|
|
|
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
|
|
|
|
|
|
- if (np)
|
|
|
- irq = platform_get_irq(pdev, 0);
|
|
|
-
|
|
|
- if (!np || irq <= 0)
|
|
|
- irq = IRQ_DB8500_PRCMU1;
|
|
|
+ irq = platform_get_irq(pdev, 0);
|
|
|
+ if (irq <= 0) {
|
|
|
+ dev_err(&pdev->dev, "no prcmu irq provided\n");
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
|
|
|
err = request_threaded_irq(irq, prcmu_irq_handler,
|
|
|
prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);
|
|
@@ -3131,7 +3167,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
|
|
|
if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
|
|
|
- db8500_prcmu_devs[i].platform_data = ab8500_platdata;
|
|
|
+ db8500_prcmu_devs[i].platform_data = pdata->ab_platdata;
|
|
|
db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data);
|
|
|
}
|
|
|
}
|