mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
ARM: SoC platform updates for v4.4
New and/or improved SoC support for this release:
- Marvell Berlin:
* Enable standard DT-based cpufreq
* Add CPU hotplug support
- Freescale:
* Ethernet init for i.MX7D
* Suspend/resume support for i.MX6UL
- Allwinner:
* Support for R8 chipset (used on NTC's $9 C.H.I.P board)
- Mediatek:
* SMP support for some platforms
- Uniphier:
* L2 support
* Cleaned up SMP support, etc.
+ A handful of other patches around above functionality, and a few other
smaller changes.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWQCmaAAoJEIwa5zzehBx3F/0QAKIYmvmJM3sUanNEEwhRilx+
3xhSgld7e25suLGwrNapTkd8VzVB4b8GnJhNShNk+l5WqfqICHCB4Aru2NmJHY8V
yPj5vBrgJTVMnIiH7CRDPz9IlwAkWM4MmWi4PgFuhrk1T/0wPKPNMc40OWOloTeD
gA5YmbbX1hNOqKoI/z+DK7CEdp1lHrEjeYIbnQ0SldFzkY9NKhrI784gtcz3si6E
19pFQ9LA7EtEv7aRcFOA0sazeooa2wiJ9P9L31Mn5APZBJj5H8HjyKdvOmJ8neQn
+b77Tya11Q70U57uDq69l0rl58fpy650uTwYaLNGWmUdTgOiGMWN05lvIVNrQd/R
gP+VEQDGsTH6kqOCy9gyLCmn9q9I7l0t9lwcu5TP52Xy9vqVq9rb388MkcPcsWk8
cYPvD8RcSaywZUV3YJgbYozBfVuf5rLVus6D54pMXe3N12KGaNBt8kk4co4jBwvh
b//1urA82cdlEAZ/kiqHXjRMq/ht+dxtb6sSVOJ9frxPLuc7g1z4ORC+Z0PTS5WC
zB0hMzPnTwXeqHcYpV4wP/vGtgZGpLevBkK7pKVdqKZykV8BS4FiT4HFp6Rghxs3
dxAz7JjQUle6KOX7YfuHdpLnyZFWQvLYyTn946xGKpw2QH/iWLwECpet2I87QzVs
QkEkGygPhK4QcGccxz9N
=h5xk
-----END PGP SIGNATURE-----
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Olof Johansson:
"New and/or improved SoC support for this release:
Marvell Berlin:
- Enable standard DT-based cpufreq
- Add CPU hotplug support
Freescale:
- Ethernet init for i.MX7D
- Suspend/resume support for i.MX6UL
Allwinner:
- Support for R8 chipset (used on NTC's $9 C.H.I.P board)
Mediatek:
- SMP support for some platforms
Uniphier:
- L2 support
- Cleaned up SMP support, etc.
plus a handful of other patches around above functionality, and a few
other smaller changes"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (42 commits)
ARM: uniphier: rework SMP operations to use trampoline code
ARM: uniphier: add outer cache support
Documentation: EXYNOS: Update bootloader interface on exynos542x
ARM: mvebu: add broken-idle option
ARM: orion5x: use mac_pton() helper
ARM: at91: pm: at91_pm_suspend_in_sram() must be 8-byte aligned
ARM: sunxi: Add R8 support
ARM: digicolor: select pinctrl/gpio driver
arm: berlin: add CPU hotplug support
arm: berlin: use non-self-cleared reset register to reset cpu
ARM: mediatek: add smp bringup code
ARM: mediatek: enable gpt6 on boot up to make arch timer working
soc: mediatek: Fix random hang up issue while kernel init
soc: ti: qmss: make acc queue support optional in the driver
soc: ti: add firmware file name as part of the driver
Documentation: dt: soc: Add description for knav qmss driver
ARM: S3C64XX: Use PWM lookup table for mach-smartq
ARM: S3C64XX: Use PWM lookup table for mach-hmt
ARM: S3C64XX: Use PWM lookup table for mach-crag6410
ARM: S3C64XX: Use PWM lookup table for smdk6410
...
This commit is contained in:
commit
56e0464980
70 changed files with 1888 additions and 296 deletions
|
|
@ -1,5 +1,6 @@
|
|||
menu "SOC (System On Chip) specific Drivers"
|
||||
|
||||
source "drivers/soc/brcmstb/Kconfig"
|
||||
source "drivers/soc/mediatek/Kconfig"
|
||||
source "drivers/soc/qcom/Kconfig"
|
||||
source "drivers/soc/sunxi/Kconfig"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
# Makefile for the Linux Kernel SOC specific device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/
|
||||
obj-$(CONFIG_MACH_DOVE) += dove/
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_QCOM) += qcom/
|
||||
|
|
|
|||
9
drivers/soc/brcmstb/Kconfig
Normal file
9
drivers/soc/brcmstb/Kconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
menuconfig SOC_BRCMSTB
|
||||
bool "Broadcom STB SoC drivers"
|
||||
depends on ARM
|
||||
help
|
||||
Enables drivers for the Broadcom Set-Top Box (STB) series of chips.
|
||||
This option alone enables only some support code, while the drivers
|
||||
can be enabled individually within this menu.
|
||||
|
||||
If unsure, say N.
|
||||
1
drivers/soc/brcmstb/Makefile
Normal file
1
drivers/soc/brcmstb/Makefile
Normal file
|
|
@ -0,0 +1 @@
|
|||
obj-y += common.o biuctrl.o
|
||||
116
drivers/soc/brcmstb/biuctrl.c
Normal file
116
drivers/soc/brcmstb/biuctrl.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Broadcom STB SoCs Bus Unit Interface controls
|
||||
*
|
||||
* Copyright (C) 2015, Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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) "brcmstb: " KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#define CPU_CREDIT_REG_OFFSET 0x184
|
||||
#define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
|
||||
|
||||
static void __iomem *cpubiuctrl_base;
|
||||
static bool mcp_wr_pairing_en;
|
||||
|
||||
static int __init mcp_write_pairing_set(void)
|
||||
{
|
||||
u32 creds = 0;
|
||||
|
||||
if (!cpubiuctrl_base)
|
||||
return -1;
|
||||
|
||||
creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
|
||||
if (mcp_wr_pairing_en) {
|
||||
pr_info("MCP: Enabling write pairing\n");
|
||||
writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
|
||||
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
|
||||
} else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
|
||||
pr_info("MCP: Disabling write pairing\n");
|
||||
writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
|
||||
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
|
||||
} else {
|
||||
pr_info("MCP: Write pairing already disabled\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init setup_hifcpubiuctrl_regs(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int ret = 0;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
|
||||
if (!np) {
|
||||
pr_err("missing BIU control node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cpubiuctrl_base = of_iomap(np, 0);
|
||||
if (!cpubiuctrl_base) {
|
||||
pr_err("failed to remap BIU control base\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
|
||||
out:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static u32 cpu_credit_reg_dump; /* for save/restore */
|
||||
|
||||
static int brcmstb_cpu_credit_reg_suspend(void)
|
||||
{
|
||||
if (cpubiuctrl_base)
|
||||
cpu_credit_reg_dump =
|
||||
readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void brcmstb_cpu_credit_reg_resume(void)
|
||||
{
|
||||
if (cpubiuctrl_base)
|
||||
writel_relaxed(cpu_credit_reg_dump,
|
||||
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
|
||||
}
|
||||
|
||||
static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
|
||||
.suspend = brcmstb_cpu_credit_reg_suspend,
|
||||
.resume = brcmstb_cpu_credit_reg_resume,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void __init brcmstb_biuctrl_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
setup_hifcpubiuctrl_regs();
|
||||
|
||||
ret = mcp_write_pairing_set();
|
||||
if (ret) {
|
||||
pr_err("MCP: Unable to disable write pairing!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
|
||||
#endif
|
||||
}
|
||||
33
drivers/soc/brcmstb/common.c
Normal file
33
drivers/soc/brcmstb/common.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright © 2014 NVIDIA Corporation
|
||||
* Copyright © 2015 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <soc/brcmstb/common.h>
|
||||
|
||||
static const struct of_device_id brcmstb_machine_match[] = {
|
||||
{ .compatible = "brcm,brcmstb", },
|
||||
{ }
|
||||
};
|
||||
|
||||
bool soc_is_brcmstb(void)
|
||||
{
|
||||
struct device_node *root;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return false;
|
||||
|
||||
return of_match_node(brcmstb_machine_match, root) != NULL;
|
||||
}
|
||||
|
|
@ -725,10 +725,6 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
|||
pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN);
|
||||
pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
|
||||
pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
|
||||
pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
|
||||
pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
|
||||
if (pwrap_is_mt8135(wrp)) {
|
||||
/* enable pwrap events and pwrap bridge in AP side */
|
||||
|
|
@ -896,6 +892,12 @@ static int pwrap_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Initialize watchdog, may not be done by the bootloader */
|
||||
pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
|
||||
pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
|
||||
"mt-pmic-pwrap", wrp);
|
||||
|
|
|
|||
|
|
@ -54,12 +54,16 @@
|
|||
#define PWR_STATUS_USB BIT(25)
|
||||
|
||||
enum clk_id {
|
||||
MT8173_CLK_NONE,
|
||||
MT8173_CLK_MM,
|
||||
MT8173_CLK_MFG,
|
||||
MT8173_CLK_NONE,
|
||||
MT8173_CLK_MAX = MT8173_CLK_NONE,
|
||||
MT8173_CLK_VENC,
|
||||
MT8173_CLK_VENC_LT,
|
||||
MT8173_CLK_MAX,
|
||||
};
|
||||
|
||||
#define MAX_CLKS 2
|
||||
|
||||
struct scp_domain_data {
|
||||
const char *name;
|
||||
u32 sta_mask;
|
||||
|
|
@ -67,7 +71,8 @@ struct scp_domain_data {
|
|||
u32 sram_pdn_bits;
|
||||
u32 sram_pdn_ack_bits;
|
||||
u32 bus_prot_mask;
|
||||
enum clk_id clk_id;
|
||||
enum clk_id clk_id[MAX_CLKS];
|
||||
bool active_wakeup;
|
||||
};
|
||||
|
||||
static const struct scp_domain_data scp_domain_data[] __initconst = {
|
||||
|
|
@ -77,7 +82,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_VDE_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.clk_id = MT8173_CLK_MM,
|
||||
.clk_id = {MT8173_CLK_MM},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_VENC] = {
|
||||
.name = "venc",
|
||||
|
|
@ -85,7 +90,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_VEN_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = MT8173_CLK_MM,
|
||||
.clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_ISP] = {
|
||||
.name = "isp",
|
||||
|
|
@ -93,7 +98,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_ISP_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.clk_id = MT8173_CLK_MM,
|
||||
.clk_id = {MT8173_CLK_MM},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MM] = {
|
||||
.name = "mm",
|
||||
|
|
@ -101,7 +106,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_DIS_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.clk_id = MT8173_CLK_MM,
|
||||
.clk_id = {MT8173_CLK_MM},
|
||||
.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
|
||||
MT8173_TOP_AXI_PROT_EN_MM_M1,
|
||||
},
|
||||
|
|
@ -111,7 +116,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_VEN2_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = MT8173_CLK_MM,
|
||||
.clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_AUDIO] = {
|
||||
.name = "audio",
|
||||
|
|
@ -119,7 +124,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_AUDIO_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = MT8173_CLK_NONE,
|
||||
.clk_id = {MT8173_CLK_NONE},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_USB] = {
|
||||
.name = "usb",
|
||||
|
|
@ -127,7 +132,8 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_USB_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.clk_id = MT8173_CLK_NONE,
|
||||
.clk_id = {MT8173_CLK_NONE},
|
||||
.active_wakeup = true,
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
.name = "mfg_async",
|
||||
|
|
@ -135,7 +141,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = 0,
|
||||
.clk_id = MT8173_CLK_MFG,
|
||||
.clk_id = {MT8173_CLK_MFG},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG_2D] = {
|
||||
.name = "mfg_2d",
|
||||
|
|
@ -143,7 +149,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_MFG_2D_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.clk_id = MT8173_CLK_NONE,
|
||||
.clk_id = {MT8173_CLK_NONE},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG] = {
|
||||
.name = "mfg",
|
||||
|
|
@ -151,7 +157,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
|
|||
.ctl_offs = SPM_MFG_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(13, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(21, 16),
|
||||
.clk_id = MT8173_CLK_NONE,
|
||||
.clk_id = {MT8173_CLK_NONE},
|
||||
.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
|
||||
MT8173_TOP_AXI_PROT_EN_MFG_M0 |
|
||||
MT8173_TOP_AXI_PROT_EN_MFG_M1 |
|
||||
|
|
@ -166,12 +172,13 @@ struct scp;
|
|||
struct scp_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
struct scp *scp;
|
||||
struct clk *clk;
|
||||
struct clk *clk[MAX_CLKS];
|
||||
u32 sta_mask;
|
||||
void __iomem *ctl_addr;
|
||||
u32 sram_pdn_bits;
|
||||
u32 sram_pdn_ack_bits;
|
||||
u32 bus_prot_mask;
|
||||
bool active_wakeup;
|
||||
};
|
||||
|
||||
struct scp {
|
||||
|
|
@ -212,11 +219,16 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
|
||||
ret = clk_prepare_enable(scpd->clk[i]);
|
||||
if (ret) {
|
||||
for (--i; i >= 0; i--)
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
|
||||
if (scpd->clk) {
|
||||
ret = clk_prepare_enable(scpd->clk);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
}
|
||||
}
|
||||
|
||||
val = readl(ctl_addr);
|
||||
|
|
@ -282,7 +294,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
return 0;
|
||||
|
||||
err_pwr_ack:
|
||||
clk_disable_unprepare(scpd->clk);
|
||||
for (i = MAX_CLKS - 1; i >= 0; i--) {
|
||||
if (scpd->clk[i])
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
}
|
||||
err_clk:
|
||||
dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
|
||||
|
||||
|
|
@ -299,6 +314,7 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
u32 pdn_ack = scpd->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (scpd->bus_prot_mask) {
|
||||
ret = mtk_infracfg_set_bus_protection(scp->infracfg,
|
||||
|
|
@ -360,8 +376,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
expired = true;
|
||||
}
|
||||
|
||||
if (scpd->clk)
|
||||
clk_disable_unprepare(scpd->clk);
|
||||
for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
|
||||
clk_disable_unprepare(scpd->clk[i]);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -371,11 +387,22 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool scpsys_active_wakeup(struct device *dev)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
struct scp_domain *scpd;
|
||||
|
||||
genpd = pd_to_genpd(dev->pm_domain);
|
||||
scpd = container_of(genpd, struct scp_domain, genpd);
|
||||
|
||||
return scpd->active_wakeup;
|
||||
}
|
||||
|
||||
static int __init scpsys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct genpd_onecell_data *pd_data;
|
||||
struct resource *res;
|
||||
int i, ret;
|
||||
int i, j, ret;
|
||||
struct scp *scp;
|
||||
struct clk *clk[MT8173_CLK_MAX];
|
||||
|
||||
|
|
@ -405,6 +432,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(clk[MT8173_CLK_MFG]))
|
||||
return PTR_ERR(clk[MT8173_CLK_MFG]);
|
||||
|
||||
clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
|
||||
if (IS_ERR(clk[MT8173_CLK_VENC]))
|
||||
return PTR_ERR(clk[MT8173_CLK_VENC]);
|
||||
|
||||
clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
|
||||
if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
|
||||
return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
|
||||
|
||||
scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
|
||||
"infracfg");
|
||||
if (IS_ERR(scp->infracfg)) {
|
||||
|
|
@ -428,12 +463,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
|
|||
scpd->sram_pdn_bits = data->sram_pdn_bits;
|
||||
scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
|
||||
scpd->bus_prot_mask = data->bus_prot_mask;
|
||||
if (data->clk_id != MT8173_CLK_NONE)
|
||||
scpd->clk = clk[data->clk_id];
|
||||
scpd->active_wakeup = data->active_wakeup;
|
||||
for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
|
||||
scpd->clk[j] = clk[data->clk_id[j]];
|
||||
|
||||
genpd->name = data->name;
|
||||
genpd->power_off = scpsys_power_off;
|
||||
genpd->power_on = scpsys_power_on;
|
||||
genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
|
||||
|
||||
/*
|
||||
* Initially turn on all domains to make the domains usable
|
||||
|
|
|
|||
|
|
@ -135,9 +135,10 @@ struct knav_pdsp_info {
|
|||
};
|
||||
void __iomem *intd;
|
||||
u32 __iomem *iram;
|
||||
const char *firmware;
|
||||
u32 id;
|
||||
struct list_head list;
|
||||
bool loaded;
|
||||
bool started;
|
||||
};
|
||||
|
||||
struct knav_qmgr_info {
|
||||
|
|
|
|||
|
|
@ -486,8 +486,8 @@ struct knav_range_ops knav_acc_range_ops = {
|
|||
* Return 0 on success or error
|
||||
*/
|
||||
int knav_init_acc_range(struct knav_device *kdev,
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
struct device_node *node,
|
||||
struct knav_range_info *range)
|
||||
{
|
||||
struct knav_acc_channel *acc;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
|
|
@ -530,6 +530,12 @@ int knav_init_acc_range(struct knav_device *kdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pdsp->started) {
|
||||
dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
|
||||
info->pdsp_id, range->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->pdsp = pdsp;
|
||||
channels = range->num_queues;
|
||||
if (of_get_property(node, "multi-queue", NULL)) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
|
|||
idx < (kdev)->num_queues_in_use; \
|
||||
idx++, inst = knav_queue_idx_to_inst(kdev, idx))
|
||||
|
||||
/* All firmware file names end up here. List the firmware file names below.
|
||||
* Newest followed by older ones. Search is done from start of the array
|
||||
* until a firmware file is found.
|
||||
*/
|
||||
const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
|
||||
|
||||
/**
|
||||
* knav_queue_notify: qmss queue notfier call
|
||||
*
|
||||
|
|
@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
struct device *dev = kdev->dev;
|
||||
struct knav_pdsp_info *pdsp;
|
||||
struct device_node *child;
|
||||
int ret;
|
||||
|
||||
for_each_child_of_node(pdsps, child) {
|
||||
pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
|
||||
|
|
@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
return -ENOMEM;
|
||||
}
|
||||
pdsp->name = knav_queue_find_name(child);
|
||||
ret = of_property_read_string(child, "firmware",
|
||||
&pdsp->firmware);
|
||||
if (ret < 0 || !pdsp->firmware) {
|
||||
dev_err(dev, "unknown firmware for pdsp %s\n",
|
||||
pdsp->name);
|
||||
devm_kfree(dev, pdsp);
|
||||
continue;
|
||||
}
|
||||
dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
|
||||
pdsp->firmware);
|
||||
|
||||
pdsp->iram =
|
||||
knav_queue_map_reg(kdev, child,
|
||||
KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
|
||||
|
|
@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
|
|||
}
|
||||
of_property_read_u32(child, "id", &pdsp->id);
|
||||
list_add_tail(&pdsp->list, &kdev->pdsps);
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
|
||||
dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
|
||||
pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
|
||||
pdsp->intd, pdsp->firmware);
|
||||
pdsp->intd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
|
|||
dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
|
||||
return ret;
|
||||
}
|
||||
pdsp->loaded = false;
|
||||
pdsp->started = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
|
|||
{
|
||||
int i, ret, fwlen;
|
||||
const struct firmware *fw;
|
||||
bool found = false;
|
||||
u32 *fwdata;
|
||||
|
||||
ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
|
||||
if (ret) {
|
||||
dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
|
||||
pdsp->firmware, pdsp->name);
|
||||
return ret;
|
||||
for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
|
||||
if (knav_acc_firmwares[i]) {
|
||||
ret = request_firmware(&fw,
|
||||
knav_acc_firmwares[i],
|
||||
kdev->dev);
|
||||
if (!ret) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
dev_err(kdev->dev, "failed to get firmware for pdsp\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
|
||||
knav_acc_firmwares[i]);
|
||||
|
||||
writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
|
||||
/* download the firmware */
|
||||
fwdata = (u32 *)fw->data;
|
||||
|
|
@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
|
|||
int ret;
|
||||
|
||||
knav_queue_stop_pdsps(kdev);
|
||||
/* now load them all */
|
||||
/* now load them all. We return success even if pdsp
|
||||
* is not loaded as acc channels are optional on having
|
||||
* firmware availability in the system. We set the loaded
|
||||
* and stated flag and when initialize the acc range, check
|
||||
* it and init the range only if pdsp is started.
|
||||
*/
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_load_pdsp(kdev, pdsp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!ret)
|
||||
pdsp->loaded = true;
|
||||
}
|
||||
|
||||
for_each_pdsp(kdev, pdsp) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
WARN_ON(ret);
|
||||
if (pdsp->loaded) {
|
||||
ret = knav_queue_start_pdsp(kdev, pdsp);
|
||||
if (!ret)
|
||||
pdsp->started = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue