Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC-related driver updates from Olof Johansson: "Various driver updates for platforms and a couple of the small driver subsystems we merge through our tree: Among the larger pieces: - Power management improvements for TI am335x and am437x (RTC suspend/wake) - Misc new additions for Amlogic (socinfo updates) - ZynqMP FPGA manager - Nvidia improvements for reset/powergate handling - PMIC wrapper for Mediatek MT8516 - Misc fixes/improvements for ARM SCMI, TEE, NXP i.MX SCU drivers" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (57 commits) soc: aspeed: fix Kconfig soc: add aspeed folder and misc drivers spi: zynqmp: Fix build break soc: imx: Add generic i.MX8 SoC driver MAINTAINERS: Update email for Qualcomm SoC maintainer memory: tegra: Fix a typos for "fdcdwr2" mc client Revert "ARM: tegra: Restore memory arbitration on resume from LP1 on Tegra30+" memory: tegra: Replace readl-writel with mc_readl-mc_writel memory: tegra: Fix integer overflow on tick value calculation memory: tegra: Fix missed registers values latching ARM: tegra: cpuidle: Handle tick broadcasting within cpuidle core on Tegra20/30 optee: allow to work without static shared memory soc/tegra: pmc: Move powergate initialisation to probe soc/tegra: pmc: Remove reset sysfs entries on error soc/tegra: pmc: Fix reset sources and levels soc: amlogic: meson-gx-pwrc-vpu: Add support for G12A soc: amlogic: meson-gx-pwrc-vpu: Fix power on/off register bitmask fpga manager: Adding FPGA Manager support for Xilinx zynqmp dt-bindings: fpga: Add bindings for ZynqMP fpga driver firmware: xilinx: Add fpga API's ...
Этот коммит содержится в:
@@ -537,6 +537,9 @@
|
||||
#define MCONNID_SHIFT 0
|
||||
#define MCONNID_MASK (0xff << 0)
|
||||
|
||||
/* READ_WRITE_LEVELING_CONTROL */
|
||||
#define RDWRLVLFULL_START 0x80000000
|
||||
|
||||
/* DDR_PHY_CTRL_1 - EMIF4D */
|
||||
#define DLL_SLAVE_DLY_CTRL_SHIFT_4D 4
|
||||
#define DLL_SLAVE_DLY_CTRL_MASK_4D (0xFF << 4)
|
||||
@@ -598,6 +601,7 @@ extern struct emif_regs_amx3 ti_emif_regs_amx3;
|
||||
|
||||
void ti_emif_save_context(void);
|
||||
void ti_emif_restore_context(void);
|
||||
void ti_emif_run_hw_leveling(void);
|
||||
void ti_emif_enter_sr(void);
|
||||
void ti_emif_exit_sr(void);
|
||||
void ti_emif_abort_sr(void);
|
||||
|
@@ -51,6 +51,9 @@
|
||||
#define MC_EMEM_ADR_CFG 0x54
|
||||
#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
|
||||
|
||||
#define MC_TIMING_CONTROL 0xfc
|
||||
#define MC_TIMING_UPDATE BIT(0)
|
||||
|
||||
static const struct of_device_id tegra_mc_of_match[] = {
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
{ .compatible = "nvidia,tegra20-mc-gart", .data = &tegra20_mc_soc },
|
||||
@@ -74,7 +77,7 @@ static const struct of_device_id tegra_mc_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
|
||||
|
||||
static int terga_mc_block_dma_common(struct tegra_mc *mc,
|
||||
static int tegra_mc_block_dma_common(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -90,13 +93,13 @@ static int terga_mc_block_dma_common(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool terga_mc_dma_idling_common(struct tegra_mc *mc,
|
||||
static bool tegra_mc_dma_idling_common(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
return (mc_readl(mc, rst->status) & BIT(rst->bit)) != 0;
|
||||
}
|
||||
|
||||
static int terga_mc_unblock_dma_common(struct tegra_mc *mc,
|
||||
static int tegra_mc_unblock_dma_common(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -112,17 +115,17 @@ static int terga_mc_unblock_dma_common(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int terga_mc_reset_status_common(struct tegra_mc *mc,
|
||||
static int tegra_mc_reset_status_common(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
return (mc_readl(mc, rst->control) & BIT(rst->bit)) != 0;
|
||||
}
|
||||
|
||||
const struct tegra_mc_reset_ops terga_mc_reset_ops_common = {
|
||||
.block_dma = terga_mc_block_dma_common,
|
||||
.dma_idling = terga_mc_dma_idling_common,
|
||||
.unblock_dma = terga_mc_unblock_dma_common,
|
||||
.reset_status = terga_mc_reset_status_common,
|
||||
const struct tegra_mc_reset_ops tegra_mc_reset_ops_common = {
|
||||
.block_dma = tegra_mc_block_dma_common,
|
||||
.dma_idling = tegra_mc_dma_idling_common,
|
||||
.unblock_dma = tegra_mc_unblock_dma_common,
|
||||
.reset_status = tegra_mc_reset_status_common,
|
||||
};
|
||||
|
||||
static inline struct tegra_mc *reset_to_mc(struct reset_controller_dev *rcdev)
|
||||
@@ -282,25 +285,28 @@ static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
|
||||
u32 value;
|
||||
|
||||
/* compute the number of MC clock cycles per tick */
|
||||
tick = mc->tick * clk_get_rate(mc->clk);
|
||||
tick = (unsigned long long)mc->tick * clk_get_rate(mc->clk);
|
||||
do_div(tick, NSEC_PER_SEC);
|
||||
|
||||
value = readl(mc->regs + MC_EMEM_ARB_CFG);
|
||||
value = mc_readl(mc, MC_EMEM_ARB_CFG);
|
||||
value &= ~MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK;
|
||||
value |= MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(tick);
|
||||
writel(value, mc->regs + MC_EMEM_ARB_CFG);
|
||||
mc_writel(mc, value, MC_EMEM_ARB_CFG);
|
||||
|
||||
/* write latency allowance defaults */
|
||||
for (i = 0; i < mc->soc->num_clients; i++) {
|
||||
const struct tegra_mc_la *la = &mc->soc->clients[i].la;
|
||||
u32 value;
|
||||
|
||||
value = readl(mc->regs + la->reg);
|
||||
value = mc_readl(mc, la->reg);
|
||||
value &= ~(la->mask << la->shift);
|
||||
value |= (la->def & la->mask) << la->shift;
|
||||
writel(value, mc->regs + la->reg);
|
||||
mc_writel(mc, value, la->reg);
|
||||
}
|
||||
|
||||
/* latch new values */
|
||||
mc_writel(mc, MC_TIMING_UPDATE, MC_TIMING_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ static inline void mc_writel(struct tegra_mc *mc, u32 value,
|
||||
writel_relaxed(value, mc->regs + offset);
|
||||
}
|
||||
|
||||
extern const struct tegra_mc_reset_ops terga_mc_reset_ops_common;
|
||||
extern const struct tegra_mc_reset_ops tegra_mc_reset_ops_common;
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
extern const struct tegra_mc_soc tegra20_mc_soc;
|
||||
|
@@ -572,7 +572,7 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
|
||||
},
|
||||
}, {
|
||||
.id = 0x34,
|
||||
.name = "fdcwr2",
|
||||
.name = "fdcdwr2",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
@@ -975,7 +975,7 @@ const struct tegra_mc_soc tegra114_mc_soc = {
|
||||
.smmu = &tegra114_smmu_soc,
|
||||
.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
|
||||
MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga_mc_reset_ops_common,
|
||||
.reset_ops = &tegra_mc_reset_ops_common,
|
||||
.resets = tegra114_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra114_mc_resets),
|
||||
};
|
||||
|
@@ -1074,7 +1074,7 @@ const struct tegra_mc_soc tegra124_mc_soc = {
|
||||
.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
|
||||
MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
|
||||
MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga_mc_reset_ops_common,
|
||||
.reset_ops = &tegra_mc_reset_ops_common,
|
||||
.resets = tegra124_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra124_mc_resets),
|
||||
};
|
||||
@@ -1104,7 +1104,7 @@ const struct tegra_mc_soc tegra132_mc_soc = {
|
||||
.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
|
||||
MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
|
||||
MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga_mc_reset_ops_common,
|
||||
.reset_ops = &tegra_mc_reset_ops_common,
|
||||
.resets = tegra124_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra124_mc_resets),
|
||||
};
|
||||
|
@@ -198,7 +198,7 @@ static const struct tegra_mc_reset tegra20_mc_resets[] = {
|
||||
TEGRA20_MC_RESET(VI, 0x100, 0x178, 0x104, 14),
|
||||
};
|
||||
|
||||
static int terga20_mc_hotreset_assert(struct tegra_mc *mc,
|
||||
static int tegra20_mc_hotreset_assert(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -214,7 +214,7 @@ static int terga20_mc_hotreset_assert(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int terga20_mc_hotreset_deassert(struct tegra_mc *mc,
|
||||
static int tegra20_mc_hotreset_deassert(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -230,7 +230,7 @@ static int terga20_mc_hotreset_deassert(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int terga20_mc_block_dma(struct tegra_mc *mc,
|
||||
static int tegra20_mc_block_dma(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -246,19 +246,19 @@ static int terga20_mc_block_dma(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool terga20_mc_dma_idling(struct tegra_mc *mc,
|
||||
static bool tegra20_mc_dma_idling(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
return mc_readl(mc, rst->status) == 0;
|
||||
}
|
||||
|
||||
static int terga20_mc_reset_status(struct tegra_mc *mc,
|
||||
static int tegra20_mc_reset_status(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
return (mc_readl(mc, rst->reset) & BIT(rst->bit)) == 0;
|
||||
}
|
||||
|
||||
static int terga20_mc_unblock_dma(struct tegra_mc *mc,
|
||||
static int tegra20_mc_unblock_dma(struct tegra_mc *mc,
|
||||
const struct tegra_mc_reset *rst)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -274,13 +274,13 @@ static int terga20_mc_unblock_dma(struct tegra_mc *mc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct tegra_mc_reset_ops terga20_mc_reset_ops = {
|
||||
.hotreset_assert = terga20_mc_hotreset_assert,
|
||||
.hotreset_deassert = terga20_mc_hotreset_deassert,
|
||||
.block_dma = terga20_mc_block_dma,
|
||||
.dma_idling = terga20_mc_dma_idling,
|
||||
.unblock_dma = terga20_mc_unblock_dma,
|
||||
.reset_status = terga20_mc_reset_status,
|
||||
static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
|
||||
.hotreset_assert = tegra20_mc_hotreset_assert,
|
||||
.hotreset_deassert = tegra20_mc_hotreset_deassert,
|
||||
.block_dma = tegra20_mc_block_dma,
|
||||
.dma_idling = tegra20_mc_dma_idling,
|
||||
.unblock_dma = tegra20_mc_unblock_dma,
|
||||
.reset_status = tegra20_mc_reset_status,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra20_mc_soc = {
|
||||
@@ -290,7 +290,7 @@ const struct tegra_mc_soc tegra20_mc_soc = {
|
||||
.client_id_mask = 0x3f,
|
||||
.intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
|
||||
MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga20_mc_reset_ops,
|
||||
.reset_ops = &tegra20_mc_reset_ops,
|
||||
.resets = tegra20_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra20_mc_resets),
|
||||
};
|
||||
|
@@ -1132,7 +1132,7 @@ const struct tegra_mc_soc tegra210_mc_soc = {
|
||||
.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
|
||||
MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
|
||||
MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga_mc_reset_ops_common,
|
||||
.reset_ops = &tegra_mc_reset_ops_common,
|
||||
.resets = tegra210_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra210_mc_resets),
|
||||
};
|
||||
|
@@ -726,7 +726,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
|
||||
},
|
||||
}, {
|
||||
.id = 0x34,
|
||||
.name = "fdcwr2",
|
||||
.name = "fdcdwr2",
|
||||
.swgroup = TEGRA_SWGROUP_NV2,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
@@ -999,7 +999,7 @@ const struct tegra_mc_soc tegra30_mc_soc = {
|
||||
.smmu = &tegra30_smmu_soc,
|
||||
.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
|
||||
MC_INT_DECERR_EMEM,
|
||||
.reset_ops = &terga_mc_reset_ops_common,
|
||||
.reset_ops = &tegra_mc_reset_ops_common,
|
||||
.resets = tegra30_mc_resets,
|
||||
.num_resets = ARRAY_SIZE(tegra30_mc_resets),
|
||||
};
|
||||
|
@@ -138,6 +138,9 @@ static int ti_emif_alloc_sram(struct device *dev,
|
||||
emif_data->pm_functions.exit_sr =
|
||||
sram_resume_address(emif_data,
|
||||
(unsigned long)ti_emif_exit_sr);
|
||||
emif_data->pm_functions.run_hw_leveling =
|
||||
sram_resume_address(emif_data,
|
||||
(unsigned long)ti_emif_run_hw_leveling);
|
||||
|
||||
emif_data->pm_data.regs_virt =
|
||||
(struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt;
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700
|
||||
|
||||
#define EMIF_SDCFG_TYPE_DDR2 0x2 << SDRAM_TYPE_SHIFT
|
||||
#define EMIF_SDCFG_TYPE_DDR3 0x3 << SDRAM_TYPE_SHIFT
|
||||
#define EMIF_STATUS_READY 0x4
|
||||
|
||||
#define AM43XX_EMIF_PHY_CTRL_REG_COUNT 0x120
|
||||
@@ -244,6 +245,46 @@ emif_skip_restore_extra_regs:
|
||||
mov pc, lr
|
||||
ENDPROC(ti_emif_restore_context)
|
||||
|
||||
/*
|
||||
* void ti_emif_run_hw_leveling(void)
|
||||
*
|
||||
* Used during resume to run hardware leveling again and restore the
|
||||
* configuration of the EMIF PHY, only for DDR3.
|
||||
*/
|
||||
ENTRY(ti_emif_run_hw_leveling)
|
||||
adr r4, ti_emif_pm_sram_data
|
||||
ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
|
||||
|
||||
ldr r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
|
||||
orr r3, r3, #RDWRLVLFULL_START
|
||||
ldr r2, [r0, #EMIF_SDRAM_CONFIG]
|
||||
and r2, r2, #SDRAM_TYPE_MASK
|
||||
cmp r2, #EMIF_SDCFG_TYPE_DDR3
|
||||
bne skip_hwlvl
|
||||
|
||||
str r3, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
|
||||
|
||||
/*
|
||||
* If EMIF registers are touched during initial stage of HW
|
||||
* leveling sequence there will be an L3 NOC timeout error issued
|
||||
* as the EMIF will not respond, which is not fatal, but it is
|
||||
* avoidable. This small wait loop is enough time for this condition
|
||||
* to clear, even at worst case of CPU running at max speed of 1Ghz.
|
||||
*/
|
||||
mov r2, #0x2000
|
||||
1:
|
||||
subs r2, r2, #0x1
|
||||
bne 1b
|
||||
|
||||
/* Bit clears when operation is complete */
|
||||
2: ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_CONTROL]
|
||||
tst r1, #RDWRLVLFULL_START
|
||||
bne 2b
|
||||
|
||||
skip_hwlvl:
|
||||
mov pc, lr
|
||||
ENDPROC(ti_emif_run_hw_leveling)
|
||||
|
||||
/*
|
||||
* void ti_emif_enter_sr(void)
|
||||
*
|
||||
|
Ссылка в новой задаче
Block a user