AT91 SoC for 5.7
- Rework PM to support sam9x60 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEycoQi/giopmpPgB12wIijOdRNOUFAl53JhgACgkQ2wIijOdR NOUEkw//eB3U+hdMIKY0C0u7XaGTh1hT3WwTGFG6F3eWpX4kh+RiZNmp/xNsifE5 yeI5ILZHJniEysGf0xCc0yV63Bm9mEYcPLfZDXOVezjVRjnf5Cd8dMNeXWFF+2Sw 5EgMV4l8IgKxWMIZ6Y0fhozJyLtfnTjav2FyciBJF3l409rRpn6l8YVq4sqY0XWq ta1OoEJuOukXjTeJDwtoPZVeN1w+V25GFKwCUvko/784706qyzZbtqyGzjON8HqI 6OGY3L2dEm8LLL4LmRE98fKczo0s3hoolWtB3jQa+kvNJpLpUg51TJWlc/TqQaH1 ugtAWPuk9UeLZswRWFvVQyGVxaimlq2gH6jf8ZoGTGJsZ2GEe2Kn+KCpbP4UOvy1 OgTvh5MBDfIEpcOzqdoHcu7G43Ke96Ra+ZniCl/7bW0BTLGSDtofz9P4k5i00DRd i57R3ngK4qMjnW8vInfwuqqFwV5VwwbAm9wdScyfUI/sAvGHjom1GChQQiXlf4DA ll2Lvpy5TgbsTYqoy/QdVq324WWQi6ZK8TphsJBJi91grfBmd366C//ssQ/UINmv OC6jcqnkMYtxNONShG2a9W2dOtceA6irXq/gK3kp6Wj6l+z610XKirzJ0Yc/BAXI EDNdnejN4twC9UJCygCl+UK1wbFB6rAtdPsHICZvm83rHNfHPW4= =A2LQ -----END PGP SIGNATURE----- Merge tag 'at91-5.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into arm/soc AT91 SoC for 5.7 - Rework PM to support sam9x60 * tag 'at91-5.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux: ARM: at91: pm: add quirk for sam9x60's ulp1 ARM: at91: pm: add plla disable/enable support for sam9x60 clk: at91: move sam9x60's PLL register offsets to PMC header ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S ARM: at91: pm: add pmc_version member to at91_pm_data ARM: at91: pm: add macros for plla disable/enable ARM: at91: pm: revert do not disable/enable PLLA for ULP modes ARM: at91: pm: use proper master clock register offset ARM: at91: Drop unneeded select of COMMON_CLK Link: https://lore.kernel.org/r/20200322090116.GA208895@piout.net Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
ec18b456be
arch/arm/mach-at91
drivers/clk/at91
include/linux/clk
@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK
|
||||
|
||||
config COMMON_CLK_AT91
|
||||
bool
|
||||
select COMMON_CLK
|
||||
select MFD_SYSCON
|
||||
|
||||
config HAVE_AT91_SMD
|
||||
|
@ -736,13 +736,36 @@ backup_default:
|
||||
|
||||
struct pmc_info {
|
||||
unsigned long uhp_udp_mask;
|
||||
unsigned long mckr;
|
||||
unsigned long version;
|
||||
};
|
||||
|
||||
static const struct pmc_info pmc_infos[] __initconst = {
|
||||
{ .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
|
||||
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
|
||||
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP },
|
||||
{ .uhp_udp_mask = 0 },
|
||||
{
|
||||
.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{ .uhp_udp_mask = 0,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
|
||||
.mckr = 0x28,
|
||||
.version = AT91_PMC_V2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_pmc_ids[] __initconst = {
|
||||
@ -757,7 +780,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
|
||||
{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
|
||||
|
||||
pmc = of_id->data;
|
||||
soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
|
||||
soc_pm.data.pmc_mckr_offset = pmc->mckr;
|
||||
soc_pm.data.pmc_version = pmc->version;
|
||||
|
||||
if (pm_idle)
|
||||
arm_pm_idle = pm_idle;
|
||||
|
@ -33,6 +33,8 @@ struct at91_pm_data {
|
||||
void __iomem *sfrbu;
|
||||
unsigned int standby_mode;
|
||||
unsigned int suspend_mode;
|
||||
unsigned int pmc_mckr_offset;
|
||||
unsigned int pmc_version;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -12,6 +12,10 @@ int main(void)
|
||||
DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
|
||||
DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc));
|
||||
DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu));
|
||||
DEFINE(PM_DATA_PMC_MCKR_OFFSET, offsetof(struct at91_pm_data,
|
||||
pmc_mckr_offset));
|
||||
DEFINE(PM_DATA_PMC_VERSION, offsetof(struct at91_pm_data,
|
||||
pmc_version));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
pmc .req r0
|
||||
tmp1 .req r4
|
||||
tmp2 .req r5
|
||||
tmp3 .req r6
|
||||
|
||||
/*
|
||||
* Wait until master clock is ready (after switching master clock source)
|
||||
@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram)
|
||||
str tmp1, .memtype
|
||||
ldr tmp1, [r0, #PM_DATA_MODE]
|
||||
str tmp1, .pm_mode
|
||||
ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
|
||||
str tmp1, .mckr_offset
|
||||
ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
|
||||
str tmp1, .pmc_version
|
||||
/* Both ldrne below are here to preload their address in the TLB */
|
||||
ldr tmp1, [r0, #PM_DATA_SHDWC]
|
||||
str tmp1, .shdwc
|
||||
cmp tmp1, #0
|
||||
ldrne tmp2, [tmp1, #0]
|
||||
ldr tmp1, [r0, #PM_DATA_SFRBU]
|
||||
str tmp1, .sfr
|
||||
str tmp1, .sfrbu
|
||||
cmp tmp1, #0
|
||||
ldrne tmp2, [tmp1, #0x10]
|
||||
|
||||
@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram)
|
||||
ENTRY(at91_backup_mode)
|
||||
/* Switch the master clock source to slow clock. */
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp2, .mckr_offset
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/*BUMEN*/
|
||||
ldr r0, .sfr
|
||||
ldr r0, .sfrbu
|
||||
mov tmp1, #0x1
|
||||
str tmp1, [r0, #0x10]
|
||||
|
||||
@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode)
|
||||
*/
|
||||
.macro at91_pm_ulp1_mode
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp2, .mckr_offset
|
||||
|
||||
/* Save RC oscillator state and check if it is enabled. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode)
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
/* Switch the master clock source to main clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode)
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
/* Quirk for SAM9X60's PMC */
|
||||
nop
|
||||
nop
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/* Enable the crystal oscillator */
|
||||
@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode)
|
||||
wait_moscrdy
|
||||
|
||||
/* Switch the master clock source to slow clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode)
|
||||
wait_moscsels
|
||||
|
||||
/* Switch the master clock source to main clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode)
|
||||
3:
|
||||
.endm
|
||||
|
||||
.macro at91_plla_disable
|
||||
/* Save PLLA setting and disable it */
|
||||
ldr tmp1, .pmc_version
|
||||
cmp tmp1, #AT91_PMC_V1
|
||||
beq 1f
|
||||
|
||||
#ifdef CONFIG_SOC_SAM9X60
|
||||
/* Save PLLA settings. */
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp2, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* save div. */
|
||||
mov tmp1, #0
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp2, tmp2, #0xffffff00
|
||||
orr tmp1, tmp1, tmp2
|
||||
|
||||
/* save mul. */
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
bic tmp2, tmp2, #0xffffff
|
||||
orr tmp1, tmp1, tmp2
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
/* step 2. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 3. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 4. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 5. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 7. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
b 2f
|
||||
#endif
|
||||
|
||||
1: /* Save PLLA setting and disable it */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
/* Disable PLLA. */
|
||||
mov tmp1, #AT91_PMC_PLLCOUNT
|
||||
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro at91_plla_enable
|
||||
ldr tmp2, .saved_pllar
|
||||
ldr tmp3, .pmc_version
|
||||
cmp tmp3, #AT91_PMC_V1
|
||||
beq 4f
|
||||
|
||||
#ifdef CONFIG_SOC_SAM9X60
|
||||
/* step 1. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 2. */
|
||||
ldr tmp1, =#AT91_PMC_PLL_ACR_DEFAULT_PLLA
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_ACR]
|
||||
|
||||
/* step 3. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
mov tmp3, tmp2
|
||||
bic tmp3, tmp3, #0xffffff
|
||||
orr tmp1, tmp1, tmp3
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
|
||||
/* step 8. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 9. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
|
||||
bic tmp1, tmp1, #0xff
|
||||
mov tmp3, tmp2
|
||||
bic tmp3, tmp3, #0xffffff00
|
||||
orr tmp1, tmp1, tmp3
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 10. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 11. */
|
||||
3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]
|
||||
tst tmp1, #0x1
|
||||
beq 3b
|
||||
b 2f
|
||||
#endif
|
||||
|
||||
/* Restore PLLA setting */
|
||||
4: str tmp2, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
/* Enable PLLA. */
|
||||
tst tmp2, #(AT91_PMC_MUL & 0xff0000)
|
||||
bne 1f
|
||||
tst tmp2, #(AT91_PMC_MUL & ~0xff0000)
|
||||
beq 2f
|
||||
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_LOCKA
|
||||
beq 1b
|
||||
2:
|
||||
.endm
|
||||
|
||||
ENTRY(at91_ulp_mode)
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp2, .mckr_offset
|
||||
|
||||
/* Save Master clock setting */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
str tmp1, .saved_mckr
|
||||
|
||||
/*
|
||||
* Set the Master clock source to slow clock
|
||||
*/
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
at91_plla_disable
|
||||
|
||||
ldr r0, .pm_mode
|
||||
cmp r0, #AT91_PM_ULP1
|
||||
beq ulp1_mode
|
||||
@ -352,11 +502,14 @@ ulp1_mode:
|
||||
ulp_exit:
|
||||
ldr pmc, .pmc_base
|
||||
|
||||
at91_plla_enable
|
||||
|
||||
/*
|
||||
* Restore master clock setting
|
||||
*/
|
||||
ldr tmp1, .saved_mckr
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, .mckr_offset
|
||||
ldr tmp2, .saved_mckr
|
||||
str tmp2, [pmc, tmp1]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh)
|
||||
.word 0
|
||||
.shdwc:
|
||||
.word 0
|
||||
.sfr:
|
||||
.sfrbu:
|
||||
.word 0
|
||||
.memtype:
|
||||
.word 0
|
||||
.pm_mode:
|
||||
.word 0
|
||||
.mckr_offset:
|
||||
.word 0
|
||||
.pmc_version:
|
||||
.word 0
|
||||
.saved_mckr:
|
||||
.word 0
|
||||
.saved_pllar:
|
||||
.word 0
|
||||
.saved_sam9_lpr:
|
||||
.word 0
|
||||
.saved_sam9_lpr1:
|
||||
|
@ -14,27 +14,8 @@
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
#define PMC_PLL_CTRL0 0xc
|
||||
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
|
||||
#define PMC_PLL_CTRL0_ENPLL BIT(28)
|
||||
#define PMC_PLL_CTRL0_ENPLLCK BIT(29)
|
||||
#define PMC_PLL_CTRL0_ENLOCK BIT(31)
|
||||
|
||||
#define PMC_PLL_CTRL1 0x10
|
||||
#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
|
||||
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
|
||||
|
||||
#define PMC_PLL_ACR 0x18
|
||||
#define PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL
|
||||
#define PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL
|
||||
#define PMC_PLL_ACR_UTMIVR BIT(12)
|
||||
#define PMC_PLL_ACR_UTMIBG BIT(13)
|
||||
#define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24)
|
||||
|
||||
#define PMC_PLL_UPDT 0x1c
|
||||
#define PMC_PLL_UPDT_UPDATE BIT(8)
|
||||
|
||||
#define PMC_PLL_ISR0 0xec
|
||||
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
|
||||
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
|
||||
|
||||
#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
|
||||
#define UPLL_DIV 2
|
||||
@ -59,7 +40,7 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
regmap_read(regmap, PMC_PLL_ISR0, &status);
|
||||
regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);
|
||||
|
||||
return !!(status & BIT(id));
|
||||
}
|
||||
@ -74,12 +55,12 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(pll->lock, flags);
|
||||
regmap_write(regmap, PMC_PLL_UPDT, pll->id);
|
||||
regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id);
|
||||
|
||||
regmap_read(regmap, PMC_PLL_CTRL0, &val);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
|
||||
div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
|
||||
|
||||
regmap_read(regmap, PMC_PLL_CTRL1, &val);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
|
||||
mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
|
||||
|
||||
if (sam9x60_pll_ready(regmap, pll->id) &&
|
||||
@ -88,39 +69,39 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Recommended value for PMC_PLL_ACR */
|
||||
/* Recommended value for AT91_PMC_PLL_ACR */
|
||||
if (pll->characteristics->upll)
|
||||
val = PMC_PLL_ACR_DEFAULT_UPLL;
|
||||
val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
|
||||
else
|
||||
val = PMC_PLL_ACR_DEFAULT_PLLA;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
regmap_write(regmap, PMC_PLL_CTRL1,
|
||||
regmap_write(regmap, AT91_PMC_PLL_CTRL1,
|
||||
FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
|
||||
|
||||
if (pll->characteristics->upll) {
|
||||
/* Enable the UTMI internal bandgap */
|
||||
val |= PMC_PLL_ACR_UTMIBG;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val |= AT91_PMC_PLL_ACR_UTMIBG;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
udelay(10);
|
||||
|
||||
/* Enable the UTMI internal regulator */
|
||||
val |= PMC_PLL_ACR_UTMIVR;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val |= AT91_PMC_PLL_ACR_UTMIVR;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
regmap_update_bits(regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
regmap_write(regmap, PMC_PLL_CTRL0,
|
||||
PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
|
||||
PMC_PLL_CTRL0_ENPLLCK | pll->div);
|
||||
regmap_write(regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL |
|
||||
AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div);
|
||||
|
||||
regmap_update_bits(regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
while (!sam9x60_pll_ready(regmap, pll->id))
|
||||
cpu_relax();
|
||||
@ -144,22 +125,24 @@ static void sam9x60_pll_unprepare(struct clk_hw *hw)
|
||||
|
||||
spin_lock_irqsave(pll->lock, flags);
|
||||
|
||||
regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
|
||||
regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
|
||||
PMC_PLL_CTRL0_ENPLLCK, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENPLLCK, 0);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENPLL, 0);
|
||||
|
||||
if (pll->characteristics->upll)
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_ACR,
|
||||
PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR,
|
||||
AT91_PMC_PLL_ACR_UTMIBG |
|
||||
AT91_PMC_PLL_ACR_UTMIVR, 0);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
spin_unlock_irqrestore(pll->lock, flags);
|
||||
}
|
||||
@ -316,10 +299,10 @@ sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
|
||||
pll->regmap = regmap;
|
||||
pll->lock = lock;
|
||||
|
||||
regmap_write(regmap, PMC_PLL_UPDT, id);
|
||||
regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
|
||||
regmap_write(regmap, AT91_PMC_PLL_UPDT, id);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr);
|
||||
pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
|
||||
regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr);
|
||||
pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
|
||||
|
||||
hw = &pll->hw;
|
||||
|
@ -12,6 +12,9 @@
|
||||
#ifndef AT91_PMC_H
|
||||
#define AT91_PMC_H
|
||||
|
||||
#define AT91_PMC_V1 (1) /* PMC version 1 */
|
||||
#define AT91_PMC_V2 (2) /* PMC version 2 [SAM9X60] */
|
||||
|
||||
#define AT91_PMC_SCER 0x00 /* System Clock Enable Register */
|
||||
#define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */
|
||||
|
||||
@ -30,16 +33,34 @@
|
||||
#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */
|
||||
#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */
|
||||
|
||||
#define AT91_PMC_PLL_CTRL0 0x0C /* PLL Control Register 0 [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_CTRL0_ENPLL (1 << 28) /* Enable PLL */
|
||||
#define AT91_PMC_PLL_CTRL0_ENPLLCK (1 << 29) /* Enable PLL clock for PMC */
|
||||
#define AT91_PMC_PLL_CTRL0_ENLOCK (1 << 31) /* Enable PLL lock */
|
||||
|
||||
#define AT91_PMC_PLL_CTRL1 0x10 /* PLL Control Register 1 [for SAM9X60] */
|
||||
|
||||
#define AT91_PMC_PCER 0x10 /* Peripheral Clock Enable Register */
|
||||
#define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */
|
||||
#define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status Register */
|
||||
|
||||
#define AT91_PMC_PLL_ACR 0x18 /* PLL Analog Control Register [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL /* Default PLL ACR value for UPLL */
|
||||
#define AT91_PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL /* Default PLL ACR value for PLLA */
|
||||
#define AT91_PMC_PLL_ACR_UTMIVR (1 << 12) /* UPLL Voltage regulator Control */
|
||||
#define AT91_PMC_PLL_ACR_UTMIBG (1 << 13) /* UPLL Bandgap Control */
|
||||
|
||||
#define AT91_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */
|
||||
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
|
||||
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
|
||||
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
|
||||
#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
|
||||
|
||||
#define AT91_PMC_PLL_UPDT 0x1C /* PMC PLL update register [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_UPDT_UPDATE (1 << 8) /* Update PLL settings */
|
||||
#define AT91_PMC_PLL_UPDT_ID (1 << 0) /* PLL ID */
|
||||
#define AT91_PMC_PLL_UPDT_STUPTIM (0xff << 16) /* Startup time */
|
||||
|
||||
#define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */
|
||||
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
|
||||
#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */
|
||||
@ -180,6 +201,8 @@
|
||||
#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */
|
||||
#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */
|
||||
|
||||
#define AT91_PMC_PLL_ISR0 0xEC /* PLL Interrupt Status Register 0 [SAM9X60 only] */
|
||||
|
||||
#define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
|
||||
#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */
|
||||
#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
|
||||
|
Loading…
Reference in New Issue
Block a user