Commit ec18b456 authored by Arnd Bergmann's avatar Arnd Bergmann

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.netSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents fd91e03e bb1a0e87
...@@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK ...@@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK
config COMMON_CLK_AT91 config COMMON_CLK_AT91
bool bool
select COMMON_CLK
select MFD_SYSCON select MFD_SYSCON
config HAVE_AT91_SMD config HAVE_AT91_SMD
......
...@@ -736,13 +736,36 @@ static void __init at91_pm_modes_init(void) ...@@ -736,13 +736,36 @@ static void __init at91_pm_modes_init(void)
struct pmc_info { struct pmc_info {
unsigned long uhp_udp_mask; unsigned long uhp_udp_mask;
unsigned long mckr;
unsigned long version;
}; };
static const struct pmc_info pmc_infos[] __initconst = { 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 = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP }, .mckr = 0x30,
{ .uhp_udp_mask = 0 }, .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 = { static const struct of_device_id atmel_pmc_ids[] __initconst = {
...@@ -757,7 +780,7 @@ 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,sama5d3-pmc", .data = &pmc_infos[1] },
{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
{ .compatible = "atmel,sama5d2-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 */ }, { /* sentinel */ },
}; };
...@@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void)) ...@@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
pmc = of_id->data; pmc = of_id->data;
soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask; 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) if (pm_idle)
arm_pm_idle = pm_idle; arm_pm_idle = pm_idle;
......
...@@ -33,6 +33,8 @@ struct at91_pm_data { ...@@ -33,6 +33,8 @@ struct at91_pm_data {
void __iomem *sfrbu; void __iomem *sfrbu;
unsigned int standby_mode; unsigned int standby_mode;
unsigned int suspend_mode; unsigned int suspend_mode;
unsigned int pmc_mckr_offset;
unsigned int pmc_version;
}; };
#endif #endif
......
...@@ -12,6 +12,10 @@ int main(void) ...@@ -12,6 +12,10 @@ int main(void)
DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc));
DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); 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; return 0;
} }
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
pmc .req r0 pmc .req r0
tmp1 .req r4 tmp1 .req r4
tmp2 .req r5 tmp2 .req r5
tmp3 .req r6
/* /*
* Wait until master clock is ready (after switching master clock source) * Wait until master clock is ready (after switching master clock source)
...@@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram) ...@@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram)
str tmp1, .memtype str tmp1, .memtype
ldr tmp1, [r0, #PM_DATA_MODE] ldr tmp1, [r0, #PM_DATA_MODE]
str tmp1, .pm_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 */ /* Both ldrne below are here to preload their address in the TLB */
ldr tmp1, [r0, #PM_DATA_SHDWC] ldr tmp1, [r0, #PM_DATA_SHDWC]
str tmp1, .shdwc str tmp1, .shdwc
cmp tmp1, #0 cmp tmp1, #0
ldrne tmp2, [tmp1, #0] ldrne tmp2, [tmp1, #0]
ldr tmp1, [r0, #PM_DATA_SFRBU] ldr tmp1, [r0, #PM_DATA_SFRBU]
str tmp1, .sfr str tmp1, .sfrbu
cmp tmp1, #0 cmp tmp1, #0
ldrne tmp2, [tmp1, #0x10] ldrne tmp2, [tmp1, #0x10]
...@@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram) ...@@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram)
ENTRY(at91_backup_mode) ENTRY(at91_backup_mode)
/* Switch the master clock source to slow clock. */ /* Switch the master clock source to slow clock. */
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp2, .mckr_offset
ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
/*BUMEN*/ /*BUMEN*/
ldr r0, .sfr ldr r0, .sfrbu
mov tmp1, #0x1 mov tmp1, #0x1
str tmp1, [r0, #0x10] str tmp1, [r0, #0x10]
...@@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode) ...@@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode)
*/ */
.macro at91_pm_ulp1_mode .macro at91_pm_ulp1_mode
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp2, .mckr_offset
/* Save RC oscillator state and check if it is enabled. */ /* Save RC oscillator state and check if it is enabled. */
ldr tmp1, [pmc, #AT91_PMC_SR] ldr tmp1, [pmc, #AT91_PMC_SR]
...@@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode) ...@@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode)
str tmp1, [pmc, #AT91_CKGR_MOR] str tmp1, [pmc, #AT91_CKGR_MOR]
/* Switch the master clock source to main clock */ /* Switch the master clock source to main clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode) ...@@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode)
orr tmp1, tmp1, #AT91_PMC_KEY orr tmp1, tmp1, #AT91_PMC_KEY
str tmp1, [pmc, #AT91_CKGR_MOR] str tmp1, [pmc, #AT91_CKGR_MOR]
/* Quirk for SAM9X60's PMC */
nop
nop
wait_mckrdy wait_mckrdy
/* Enable the crystal oscillator */ /* Enable the crystal oscillator */
...@@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode) ...@@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode)
wait_moscrdy wait_moscrdy
/* Switch the master clock source to slow clock */ /* Switch the master clock source to slow clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode) ...@@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode)
wait_moscsels wait_moscsels
/* Switch the master clock source to main clock */ /* Switch the master clock source to main clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode) ...@@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode)
3: 3:
.endm .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) ENTRY(at91_ulp_mode)
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp2, .mckr_offset
/* Save Master clock setting */ /* Save Master clock setting */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
str tmp1, .saved_mckr str tmp1, .saved_mckr
/* /*
* Set the Master clock source to slow clock * Set the Master clock source to slow clock
*/ */
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
at91_plla_disable
ldr r0, .pm_mode ldr r0, .pm_mode
cmp r0, #AT91_PM_ULP1 cmp r0, #AT91_PM_ULP1
beq ulp1_mode beq ulp1_mode
...@@ -352,11 +502,14 @@ ulp1_mode: ...@@ -352,11 +502,14 @@ ulp1_mode:
ulp_exit: ulp_exit:
ldr pmc, .pmc_base ldr pmc, .pmc_base
at91_plla_enable
/* /*
* Restore master clock setting * Restore master clock setting
*/ */
ldr tmp1, .saved_mckr ldr tmp1, .mckr_offset
str tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp2, .saved_mckr
str tmp2, [pmc, tmp1]
wait_mckrdy wait_mckrdy
...@@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh) ...@@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh)
.word 0 .word 0
.shdwc: .shdwc:
.word 0 .word 0
.sfr: .sfrbu:
.word 0 .word 0
.memtype: .memtype:
.word 0 .word 0
.pm_mode: .pm_mode:
.word 0 .word 0
.mckr_offset:
.word 0
.pmc_version:
.word 0
.saved_mckr: .saved_mckr:
.word 0 .word 0
.saved_pllar:
.word 0
.saved_sam9_lpr: .saved_sam9_lpr:
.word 0 .word 0
.saved_sam9_lpr1: .saved_sam9_lpr1:
......
...@@ -14,27 +14,8 @@ ...@@ -14,27 +14,8 @@
#include "pmc.h" #include "pmc.h"
#define PMC_PLL_CTRL0 0xc #define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0) #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
#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 PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1) #define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
#define UPLL_DIV 2 #define UPLL_DIV 2
...@@ -59,7 +40,7 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) ...@@ -59,7 +40,7 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
{ {
unsigned int status; unsigned int status;
regmap_read(regmap, PMC_PLL_ISR0, &status); regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);
return !!(status & BIT(id)); return !!(status & BIT(id));
} }
...@@ -74,12 +55,12 @@ static int sam9x60_pll_prepare(struct clk_hw *hw) ...@@ -74,12 +55,12 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
u32 val; u32 val;
spin_lock_irqsave(pll->lock, flags); 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); 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); mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
if (sam9x60_pll_ready(regmap, pll->id) && if (sam9x60_pll_ready(regmap, pll->id) &&
...@@ -88,39 +69,39 @@ static int sam9x60_pll_prepare(struct clk_hw *hw) ...@@ -88,39 +69,39 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
return 0; return 0;
} }
/* Recommended value for PMC_PLL_ACR */ /* Recommended value for AT91_PMC_PLL_ACR */
if (pll->characteristics->upll) if (pll->characteristics->upll)
val = PMC_PLL_ACR_DEFAULT_UPLL; val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
else else
val = PMC_PLL_ACR_DEFAULT_PLLA; val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
regmap_write(regmap, PMC_PLL_ACR, val); 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)); FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
if (pll->characteristics->upll) { if (pll->characteristics->upll) {
/* Enable the UTMI internal bandgap */ /* Enable the UTMI internal bandgap */
val |= PMC_PLL_ACR_UTMIBG; val |= AT91_PMC_PLL_ACR_UTMIBG;
regmap_write(regmap, PMC_PLL_ACR, val); regmap_write(regmap, AT91_PMC_PLL_ACR, val);
udelay(10); udelay(10);
/* Enable the UTMI internal regulator */ /* Enable the UTMI internal regulator */
val |= PMC_PLL_ACR_UTMIVR; val |= AT91_PMC_PLL_ACR_UTMIVR;
regmap_write(regmap, PMC_PLL_ACR, val); regmap_write(regmap, AT91_PMC_PLL_ACR, val);
udelay(10); udelay(10);
} }
regmap_update_bits(regmap, PMC_PLL_UPDT, regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
regmap_write(regmap, PMC_PLL_CTRL0, regmap_write(regmap, AT91_PMC_PLL_CTRL0,
PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL | AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL |
PMC_PLL_CTRL0_ENPLLCK | pll->div); AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div);
regmap_update_bits(regmap, PMC_PLL_UPDT, regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
while (!sam9x60_pll_ready(regmap, pll->id)) while (!sam9x60_pll_ready(regmap, pll->id))
cpu_relax(); cpu_relax();
...@@ -144,22 +125,24 @@ static void sam9x60_pll_unprepare(struct clk_hw *hw) ...@@ -144,22 +125,24 @@ static void sam9x60_pll_unprepare(struct clk_hw *hw)
spin_lock_irqsave(pll->lock, flags); 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, regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
PMC_PLL_CTRL0_ENPLLCK, 0); AT91_PMC_PLL_CTRL0_ENPLLCK, 0);
regmap_update_bits(pll->regmap, PMC_PLL_UPDT, regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); 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) if (pll->characteristics->upll)
regmap_update_bits(pll->regmap, PMC_PLL_ACR, regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR,
PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0); AT91_PMC_PLL_ACR_UTMIBG |
AT91_PMC_PLL_ACR_UTMIVR, 0);
regmap_update_bits(pll->regmap, PMC_PLL_UPDT, regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
spin_unlock_irqrestore(pll->lock, flags); spin_unlock_irqrestore(pll->lock, flags);
} }
...@@ -316,10 +299,10 @@ sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, ...@@ -316,10 +299,10 @@ sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
pll->regmap = regmap; pll->regmap = regmap;
pll->lock = lock; pll->lock = lock;
regmap_write(regmap, PMC_PLL_UPDT, id); regmap_write(regmap, AT91_PMC_PLL_UPDT, id);
regmap_read(regmap, PMC_PLL_CTRL0, &pllr); regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr);
pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, 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); pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
hw = &pll->hw; hw = &pll->hw;
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#ifndef AT91_PMC_H #ifndef AT91_PMC_H
#define 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_SCER 0x00 /* System Clock Enable Register */
#define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */ #define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */
...@@ -30,16 +33,34 @@ ...@@ -30,16 +33,34 @@
#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ #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_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_PCER 0x10 /* Peripheral Clock Enable Register */
#define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */ #define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */
#define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status 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_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ #define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ #define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ #define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ #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_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */ #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */
...@@ -180,6 +201,8 @@ ...@@ -180,6 +201,8 @@
#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */
#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ #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_PCER1 0x100 /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */ #define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */ #define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment