clk: at91: clk-master: split master clock in pres and divider
Split master clock in 2 controlling block: one for prescaler one for
divider. This will allow referencing correctly the CPU clock and
master clock in device trees.
Reported-by: Eugen Hristev <eugen.hristev@microchip.com>
Fixes: a64862284f ("clk: at91: sam9x60: add support compatible with
CCF")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
			
			
This commit is contained in:
		
							parent
							
								
									6beb4a3a59
								
							
						
					
					
						commit
						c05be59ca8
					
				|  | @ -12,13 +12,15 @@ | ||||||
| #include <asm/processor.h> | #include <asm/processor.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
| #include <common.h> | #include <common.h> | ||||||
|  | #include <div64.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <linux/clk/at91_pmc.h> | #include <linux/clk/at91_pmc.h> | ||||||
| 
 | 
 | ||||||
| #include "pmc.h" | #include "pmc.h" | ||||||
| 
 | 
 | ||||||
| #define UBOOT_DM_CLK_AT91_MASTER		"at91-master-clk" | #define UBOOT_DM_CLK_AT91_MASTER_PRES		"at91-master-clk-pres" | ||||||
|  | #define UBOOT_DM_CLK_AT91_MASTER_DIV		"at91-master-clk-div" | ||||||
| #define UBOOT_DM_CLK_AT91_SAMA7G5_MASTER	"at91-sama7g5-master-clk" | #define UBOOT_DM_CLK_AT91_SAMA7G5_MASTER	"at91-sama7g5-master-clk" | ||||||
| 
 | 
 | ||||||
| #define MASTER_PRES_MASK	0x7 | #define MASTER_PRES_MASK	0x7 | ||||||
|  | @ -73,7 +75,7 @@ static int clk_master_enable(struct clk *clk) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static ulong clk_master_get_rate(struct clk *clk) | static ulong clk_master_pres_get_rate(struct clk *clk) | ||||||
| { | { | ||||||
| 	struct clk_master *master = to_clk_master(clk); | 	struct clk_master *master = to_clk_master(clk); | ||||||
| 	const struct clk_master_layout *layout = master->layout; | 	const struct clk_master_layout *layout = master->layout; | ||||||
|  | @ -81,7 +83,7 @@ static ulong clk_master_get_rate(struct clk *clk) | ||||||
| 						master->characteristics; | 						master->characteristics; | ||||||
| 	ulong rate = clk_get_parent_rate(clk); | 	ulong rate = clk_get_parent_rate(clk); | ||||||
| 	unsigned int mckr; | 	unsigned int mckr; | ||||||
| 	u8 pres, div; | 	u8 pres; | ||||||
| 
 | 
 | ||||||
| 	if (!rate) | 	if (!rate) | ||||||
| 		return 0; | 		return 0; | ||||||
|  | @ -90,29 +92,21 @@ static ulong clk_master_get_rate(struct clk *clk) | ||||||
| 	mckr &= layout->mask; | 	mckr &= layout->mask; | ||||||
| 
 | 
 | ||||||
| 	pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; | 	pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; | ||||||
| 	div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; |  | ||||||
| 
 | 
 | ||||||
| 	if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) | 	if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) | ||||||
| 		rate /= 3; | 		pres = 3; | ||||||
| 	else | 	else | ||||||
| 		rate >>= pres; | 		pres = (1 << pres); | ||||||
| 
 | 
 | ||||||
| 	rate /= characteristics->divisors[div]; | 	return DIV_ROUND_CLOSEST_ULL(rate, pres); | ||||||
| 
 |  | ||||||
| 	if (rate < characteristics->output.min) |  | ||||||
| 		pr_warn("master clk is underclocked"); |  | ||||||
| 	else if (rate > characteristics->output.max) |  | ||||||
| 		pr_warn("master clk is overclocked"); |  | ||||||
| 
 |  | ||||||
| 	return rate; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct clk_ops master_ops = { | static const struct clk_ops master_pres_ops = { | ||||||
| 	.enable = clk_master_enable, | 	.enable = clk_master_enable, | ||||||
| 	.get_rate = clk_master_get_rate, | 	.get_rate = clk_master_pres_get_rate, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct clk *at91_clk_register_master(void __iomem *base, | struct clk *at91_clk_register_master_pres(void __iomem *base, | ||||||
| 		const char *name, const char * const *parent_names, | 		const char *name, const char * const *parent_names, | ||||||
| 		int num_parents, const struct clk_master_layout *layout, | 		int num_parents, const struct clk_master_layout *layout, | ||||||
| 		const struct clk_master_characteristics *characteristics, | 		const struct clk_master_characteristics *characteristics, | ||||||
|  | @ -140,7 +134,7 @@ struct clk *at91_clk_register_master(void __iomem *base, | ||||||
| 	pmc_read(master->base, master->layout->offset, &val); | 	pmc_read(master->base, master->layout->offset, &val); | ||||||
| 	clk = &master->clk; | 	clk = &master->clk; | ||||||
| 	clk->flags = CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL; | 	clk->flags = CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL; | ||||||
| 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_MASTER, name, | 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_MASTER_PRES, name, | ||||||
| 			   parent_names[val & AT91_PMC_CSS]); | 			   parent_names[val & AT91_PMC_CSS]); | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		kfree(master); | 		kfree(master); | ||||||
|  | @ -150,10 +144,81 @@ struct clk *at91_clk_register_master(void __iomem *base, | ||||||
| 	return clk; | 	return clk; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| U_BOOT_DRIVER(at91_master_clk) = { | U_BOOT_DRIVER(at91_master_pres_clk) = { | ||||||
| 	.name = UBOOT_DM_CLK_AT91_MASTER, | 	.name = UBOOT_DM_CLK_AT91_MASTER_PRES, | ||||||
| 	.id = UCLASS_CLK, | 	.id = UCLASS_CLK, | ||||||
| 	.ops = &master_ops, | 	.ops = &master_pres_ops, | ||||||
|  | 	.flags = DM_FLAG_PRE_RELOC, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static ulong clk_master_div_get_rate(struct clk *clk) | ||||||
|  | { | ||||||
|  | 	struct clk_master *master = to_clk_master(clk); | ||||||
|  | 	const struct clk_master_layout *layout = master->layout; | ||||||
|  | 	const struct clk_master_characteristics *characteristics = | ||||||
|  | 						master->characteristics; | ||||||
|  | 	ulong rate = clk_get_parent_rate(clk); | ||||||
|  | 	unsigned int mckr; | ||||||
|  | 	u8 div; | ||||||
|  | 
 | ||||||
|  | 	if (!rate) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	pmc_read(master->base, master->layout->offset, &mckr); | ||||||
|  | 	mckr &= layout->mask; | ||||||
|  | 	div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; | ||||||
|  | 
 | ||||||
|  | 	rate = DIV_ROUND_CLOSEST_ULL(rate, characteristics->divisors[div]); | ||||||
|  | 	if (rate < characteristics->output.min) | ||||||
|  | 		pr_warn("master clk is underclocked"); | ||||||
|  | 	else if (rate > characteristics->output.max) | ||||||
|  | 		pr_warn("master clk is overclocked"); | ||||||
|  | 
 | ||||||
|  | 	return rate; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct clk_ops master_div_ops = { | ||||||
|  | 	.enable = clk_master_enable, | ||||||
|  | 	.get_rate = clk_master_div_get_rate, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct clk *at91_clk_register_master_div(void __iomem *base, | ||||||
|  | 		const char *name, const char *parent_name, | ||||||
|  | 		const struct clk_master_layout *layout, | ||||||
|  | 		const struct clk_master_characteristics *characteristics) | ||||||
|  | { | ||||||
|  | 	struct clk_master *master; | ||||||
|  | 	struct clk *clk; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (!base || !name || !parent_name || !layout || !characteristics) | ||||||
|  | 		return ERR_PTR(-EINVAL); | ||||||
|  | 
 | ||||||
|  | 	master = kzalloc(sizeof(*master), GFP_KERNEL); | ||||||
|  | 	if (!master) | ||||||
|  | 		return ERR_PTR(-ENOMEM); | ||||||
|  | 
 | ||||||
|  | 	master->layout = layout; | ||||||
|  | 	master->characteristics = characteristics; | ||||||
|  | 	master->base = base; | ||||||
|  | 	master->num_parents = 1; | ||||||
|  | 
 | ||||||
|  | 	clk = &master->clk; | ||||||
|  | 	clk->flags = CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL; | ||||||
|  | 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_MASTER_DIV, name, | ||||||
|  | 			   parent_name); | ||||||
|  | 	if (ret) { | ||||||
|  | 		kfree(master); | ||||||
|  | 		clk = ERR_PTR(ret); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return clk; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(at91_master_div_clk) = { | ||||||
|  | 	.name = UBOOT_DM_CLK_AT91_MASTER_DIV, | ||||||
|  | 	.id = UCLASS_CLK, | ||||||
|  | 	.ops = &master_div_ops, | ||||||
| 	.flags = DM_FLAG_PRE_RELOC, | 	.flags = DM_FLAG_PRE_RELOC, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -97,12 +97,17 @@ sam9x60_clk_register_frac_pll(void __iomem *base, const char *name, | ||||||
| 			const struct clk_pll_characteristics *characteristics, | 			const struct clk_pll_characteristics *characteristics, | ||||||
| 			const struct clk_pll_layout *layout, bool critical); | 			const struct clk_pll_layout *layout, bool critical); | ||||||
| struct clk * | struct clk * | ||||||
| at91_clk_register_master(void __iomem *base, const char *name, | at91_clk_register_master_pres(void __iomem *base, const char *name, | ||||||
| 			const char * const *parent_names, int num_parents, | 			const char * const *parent_names, int num_parents, | ||||||
| 			const struct clk_master_layout *layout, | 			const struct clk_master_layout *layout, | ||||||
| 			const struct clk_master_characteristics *characteristics, | 			const struct clk_master_characteristics *characteristics, | ||||||
| 			const u32 *mux_table); | 			const u32 *mux_table); | ||||||
| struct clk * | struct clk * | ||||||
|  | at91_clk_register_master_div(void __iomem *base, | ||||||
|  | 			const char *name, const char *parent_name, | ||||||
|  | 			const struct clk_master_layout *layout, | ||||||
|  | 			const struct clk_master_characteristics *characteristics); | ||||||
|  | struct clk * | ||||||
| at91_clk_sama7g5_register_master(void __iomem *base, const char *name, | at91_clk_sama7g5_register_master(void __iomem *base, const char *name, | ||||||
| 			const char * const *parent_names, int num_parents, | 			const char * const *parent_names, int num_parents, | ||||||
| 			const u32 *mux_table, const u32 *clk_mux_table, | 			const u32 *mux_table, const u32 *clk_mux_table, | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ | ||||||
|  * @ID_PLL_A_FRAC:		APLL fractional clock identifier |  * @ID_PLL_A_FRAC:		APLL fractional clock identifier | ||||||
|  * @ID_PLL_A_DIV:		APLL divider clock identifier |  * @ID_PLL_A_DIV:		APLL divider clock identifier | ||||||
| 
 | 
 | ||||||
|  * @ID_MCK:			MCK clock identifier |  * @ID_MCK_DIV:			MCK DIV clock identifier | ||||||
| 
 | 
 | ||||||
|  * @ID_UTMI:			UTMI clock identifier |  * @ID_UTMI:			UTMI clock identifier | ||||||
| 
 | 
 | ||||||
|  | @ -43,6 +43,8 @@ | ||||||
|  * @ID_DDR:			DDR system clock identifier |  * @ID_DDR:			DDR system clock identifier | ||||||
|  * @ID_QSPI:			QSPI system clock identifier |  * @ID_QSPI:			QSPI system clock identifier | ||||||
|  * |  * | ||||||
|  |  * @ID_MCK_PRES:		MCK PRES clock identifier | ||||||
|  |  * | ||||||
|  * Note: if changing the values of this enums please sync them with |  * Note: if changing the values of this enums please sync them with | ||||||
|  *       device tree |  *       device tree | ||||||
|  */ |  */ | ||||||
|  | @ -60,7 +62,7 @@ enum pmc_clk_ids { | ||||||
| 	ID_PLL_A_FRAC		= 9, | 	ID_PLL_A_FRAC		= 9, | ||||||
| 	ID_PLL_A_DIV		= 10, | 	ID_PLL_A_DIV		= 10, | ||||||
| 
 | 
 | ||||||
| 	ID_MCK			= 11, | 	ID_MCK_DIV		= 11, | ||||||
| 
 | 
 | ||||||
| 	ID_UTMI			= 12, | 	ID_UTMI			= 12, | ||||||
| 
 | 
 | ||||||
|  | @ -73,6 +75,8 @@ enum pmc_clk_ids { | ||||||
| 	ID_DDR			= 17, | 	ID_DDR			= 17, | ||||||
| 	ID_QSPI			= 18, | 	ID_QSPI			= 18, | ||||||
| 
 | 
 | ||||||
|  | 	ID_MCK_PRES		= 19, | ||||||
|  | 
 | ||||||
| 	ID_MAX, | 	ID_MAX, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -93,7 +97,8 @@ static const char *clk_names[] = { | ||||||
| 	[ID_MAINCK]		= "mainck", | 	[ID_MAINCK]		= "mainck", | ||||||
| 	[ID_PLL_U_DIV]		= "upll_divpmcck", | 	[ID_PLL_U_DIV]		= "upll_divpmcck", | ||||||
| 	[ID_PLL_A_DIV]		= "plla_divpmcck", | 	[ID_PLL_A_DIV]		= "plla_divpmcck", | ||||||
| 	[ID_MCK]		= "mck", | 	[ID_MCK_PRES]		= "mck_pres", | ||||||
|  | 	[ID_MCK_DIV]		= "mck_div", | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* Fractional PLL output range. */ | /* Fractional PLL output range. */ | ||||||
|  | @ -260,10 +265,10 @@ static const struct { | ||||||
| 	u8 id; | 	u8 id; | ||||||
| 	u8 cid; | 	u8 cid; | ||||||
| } sam9x60_systemck[] = { | } sam9x60_systemck[] = { | ||||||
| 	{ .n = "ddrck",		.p = "mck", .id = 2, .cid = ID_DDR, }, | 	{ .n = "ddrck",		.p = "mck_pres", .id = 2, .cid = ID_DDR, }, | ||||||
| 	{ .n = "pck0",		.p = "prog0",    .id = 8, .cid = ID_PCK0, }, | 	{ .n = "pck0",		.p = "prog0",    .id = 8, .cid = ID_PCK0, }, | ||||||
| 	{ .n = "pck1",		.p = "prog1",    .id = 9, .cid = ID_PCK1, }, | 	{ .n = "pck1",		.p = "prog1",    .id = 9, .cid = ID_PCK1, }, | ||||||
| 	{ .n = "qspick",	.p = "mck", .id = 19, .cid = ID_QSPI, }, | 	{ .n = "qspick",	.p = "mck_pres", .id = 19, .cid = ID_QSPI, }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -508,7 +513,7 @@ static int sam9x60_clk_probe(struct udevice *dev) | ||||||
| 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c); | 		clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x60_plls[i].cid), c); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Register MCK clock. */ | 	/* Register MCK pres clock. */ | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_MAINCK]; | 	p[1] = clk_names[ID_MAINCK]; | ||||||
| 	p[2] = clk_names[ID_PLL_A_DIV]; | 	p[2] = clk_names[ID_PLL_A_DIV]; | ||||||
|  | @ -519,25 +524,36 @@ static int sam9x60_clk_probe(struct udevice *dev) | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | ||||||
| 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4, | 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4, | ||||||
| 			  fail); | 			  fail); | ||||||
| 	c = at91_clk_register_master(base, clk_names[ID_MCK], p, 4, &mck_layout, | 	c = at91_clk_register_master_pres(base, clk_names[ID_MCK_PRES], p, 4, | ||||||
| 				     &mck_characteristics, tmpclkmux); | 					  &mck_layout, &mck_characteristics, | ||||||
|  | 					  tmpclkmux); | ||||||
| 	if (IS_ERR(c)) { | 	if (IS_ERR(c)) { | ||||||
| 		ret = PTR_ERR(c); | 		ret = PTR_ERR(c); | ||||||
| 		goto fail; | 		goto fail; | ||||||
| 	} | 	} | ||||||
| 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK), c); | 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_PRES), c); | ||||||
|  | 
 | ||||||
|  | 	/* Register MCK div clock. */ | ||||||
|  | 	c = at91_clk_register_master_div(base, clk_names[ID_MCK_DIV], | ||||||
|  | 					 clk_names[ID_MCK_PRES], | ||||||
|  | 					 &mck_layout, &mck_characteristics); | ||||||
|  | 	if (IS_ERR(c)) { | ||||||
|  | 		ret = PTR_ERR(c); | ||||||
|  | 		goto fail; | ||||||
|  | 	} | ||||||
|  | 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV), c); | ||||||
| 
 | 
 | ||||||
| 	/* Register programmable clocks. */ | 	/* Register programmable clocks. */ | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_TD_SLCK]; | 	p[1] = clk_names[ID_TD_SLCK]; | ||||||
| 	p[2] = clk_names[ID_MAINCK]; | 	p[2] = clk_names[ID_MAINCK]; | ||||||
| 	p[3] = clk_names[ID_MCK]; | 	p[3] = clk_names[ID_MCK_DIV]; | ||||||
| 	p[4] = clk_names[ID_PLL_A_DIV]; | 	p[4] = clk_names[ID_PLL_A_DIV]; | ||||||
| 	p[5] = clk_names[ID_PLL_U_DIV]; | 	p[5] = clk_names[ID_PLL_U_DIV]; | ||||||
| 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | ||||||
| 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | ||||||
| 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV); | ||||||
| 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); | 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); | ||||||
| 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | ||||||
| 	for (i = 0; i < ARRAY_SIZE(sam9x60_prog); i++) { | 	for (i = 0; i < ARRAY_SIZE(sam9x60_prog); i++) { | ||||||
|  | @ -572,7 +588,7 @@ static int sam9x60_clk_probe(struct udevice *dev) | ||||||
| 	for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) { | 	for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) { | ||||||
| 		c = at91_clk_register_sam9x5_peripheral(base, &pcr_layout, | 		c = at91_clk_register_sam9x5_peripheral(base, &pcr_layout, | ||||||
| 							sam9x60_periphck[i].n, | 							sam9x60_periphck[i].n, | ||||||
| 							clk_names[ID_MCK], | 							clk_names[ID_MCK_DIV], | ||||||
| 							sam9x60_periphck[i].id, | 							sam9x60_periphck[i].id, | ||||||
| 							&r); | 							&r); | ||||||
| 		if (IS_ERR(c)) { | 		if (IS_ERR(c)) { | ||||||
|  | @ -587,7 +603,7 @@ static int sam9x60_clk_probe(struct udevice *dev) | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_TD_SLCK]; | 	p[1] = clk_names[ID_TD_SLCK]; | ||||||
| 	p[2] = clk_names[ID_MAINCK]; | 	p[2] = clk_names[ID_MAINCK]; | ||||||
| 	p[3] = clk_names[ID_MCK]; | 	p[3] = clk_names[ID_MCK_DIV]; | ||||||
| 	p[4] = clk_names[ID_PLL_A_DIV]; | 	p[4] = clk_names[ID_PLL_A_DIV]; | ||||||
| 	p[5] = clk_names[ID_PLL_U_DIV]; | 	p[5] = clk_names[ID_PLL_U_DIV]; | ||||||
| 	m[0] = 0; | 	m[0] = 0; | ||||||
|  | @ -599,7 +615,7 @@ static int sam9x60_clk_probe(struct udevice *dev) | ||||||
| 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | ||||||
| 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | ||||||
| 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV); | ||||||
| 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); | 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV); | ||||||
| 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV); | ||||||
| 	for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) { | 	for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) { | ||||||
|  |  | ||||||
|  | @ -44,7 +44,8 @@ | ||||||
|  * @ID_PLL_ETH_FRAC:		Ethernet PLL fractional clock identifier |  * @ID_PLL_ETH_FRAC:		Ethernet PLL fractional clock identifier | ||||||
|  * @ID_PLL_ETH_DIV:		Ethernet PLL divider clock identifier |  * @ID_PLL_ETH_DIV:		Ethernet PLL divider clock identifier | ||||||
| 
 | 
 | ||||||
|  * @ID_MCK0:			MCK0 clock identifier |  * @ID_MCK0_PRES:		MCK0 PRES clock identifier | ||||||
|  |  * @ID_MCK0_DIV:		MCK0 DIV clock identifier | ||||||
|  * @ID_MCK1:			MCK1 clock identifier |  * @ID_MCK1:			MCK1 clock identifier | ||||||
|  * @ID_MCK2:			MCK2 clock identifier |  * @ID_MCK2:			MCK2 clock identifier | ||||||
|  * @ID_MCK3:			MCK3 clock identifier |  * @ID_MCK3:			MCK3 clock identifier | ||||||
|  | @ -95,7 +96,7 @@ enum pmc_clk_ids { | ||||||
| 	ID_PLL_ETH_FRAC		= 20, | 	ID_PLL_ETH_FRAC		= 20, | ||||||
| 	ID_PLL_ETH_DIV		= 21, | 	ID_PLL_ETH_DIV		= 21, | ||||||
| 
 | 
 | ||||||
| 	ID_MCK0			= 22, | 	ID_MCK0_DIV		= 22, | ||||||
| 	ID_MCK1			= 23, | 	ID_MCK1			= 23, | ||||||
| 	ID_MCK2			= 24, | 	ID_MCK2			= 24, | ||||||
| 	ID_MCK3			= 25, | 	ID_MCK3			= 25, | ||||||
|  | @ -121,6 +122,8 @@ enum pmc_clk_ids { | ||||||
| 	ID_PCK6			= 42, | 	ID_PCK6			= 42, | ||||||
| 	ID_PCK7			= 43, | 	ID_PCK7			= 43, | ||||||
| 
 | 
 | ||||||
|  | 	ID_MCK0_PRES		= 44, | ||||||
|  | 
 | ||||||
| 	ID_MAX, | 	ID_MAX, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -147,7 +150,8 @@ static const char *clk_names[] = { | ||||||
| 	[ID_PLL_AUDIO_DIVPMC]	= "audiopll_divpmcck", | 	[ID_PLL_AUDIO_DIVPMC]	= "audiopll_divpmcck", | ||||||
| 	[ID_PLL_AUDIO_DIVIO]	= "audiopll_diviock", | 	[ID_PLL_AUDIO_DIVIO]	= "audiopll_diviock", | ||||||
| 	[ID_PLL_ETH_DIV]	= "ethpll_divpmcck", | 	[ID_PLL_ETH_DIV]	= "ethpll_divpmcck", | ||||||
| 	[ID_MCK0]		= "mck0", | 	[ID_MCK0_DIV]		= "mck0_div", | ||||||
|  | 	[ID_MCK0_PRES]		= "mck0_pres", | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* Fractional PLL output range. */ | /* Fractional PLL output range. */ | ||||||
|  | @ -504,7 +508,7 @@ static const struct { | ||||||
| 	struct clk_range r; | 	struct clk_range r; | ||||||
| 	u8 id; | 	u8 id; | ||||||
| } sama7g5_periphck[] = { | } sama7g5_periphck[] = { | ||||||
| 	{ .n = "pioA_clk",	.p = "mck0", .id = 11, }, | 	{ .n = "pioA_clk",	.p = "mck0_div", .id = 11, }, | ||||||
| 	{ .n = "sfr_clk",	.p = "mck1", .id = 19, }, | 	{ .n = "sfr_clk",	.p = "mck1", .id = 19, }, | ||||||
| 	{ .n = "hsmc_clk",	.p = "mck1", .id = 21, }, | 	{ .n = "hsmc_clk",	.p = "mck1", .id = 21, }, | ||||||
| 	{ .n = "xdmac0_clk",	.p = "mck1", .id = 22, }, | 	{ .n = "xdmac0_clk",	.p = "mck1", .id = 22, }, | ||||||
|  | @ -514,7 +518,7 @@ static const struct { | ||||||
| 	{ .n = "aes_clk",	.p = "mck1", .id = 27, }, | 	{ .n = "aes_clk",	.p = "mck1", .id = 27, }, | ||||||
| 	{ .n = "tzaesbasc_clk",	.p = "mck1", .id = 28, }, | 	{ .n = "tzaesbasc_clk",	.p = "mck1", .id = 28, }, | ||||||
| 	{ .n = "asrc_clk",	.p = "mck1", .id = 30, .r = { .max = 200000000, }, }, | 	{ .n = "asrc_clk",	.p = "mck1", .id = 30, .r = { .max = 200000000, }, }, | ||||||
| 	{ .n = "cpkcc_clk",	.p = "mck0", .id = 32, }, | 	{ .n = "cpkcc_clk",	.p = "mck0_div", .id = 32, }, | ||||||
| 	{ .n = "csi_clk",	.p = "mck3", .id = 33, .r = { .max = 266000000, }, }, | 	{ .n = "csi_clk",	.p = "mck3", .id = 33, .r = { .max = 266000000, }, }, | ||||||
| 	{ .n = "csi2dc_clk",	.p = "mck3", .id = 34, .r = { .max = 266000000, }, }, | 	{ .n = "csi2dc_clk",	.p = "mck3", .id = 34, .r = { .max = 266000000, }, }, | ||||||
| 	{ .n = "eic_clk",	.p = "mck1", .id = 37, }, | 	{ .n = "eic_clk",	.p = "mck1", .id = 37, }, | ||||||
|  | @ -1210,7 +1214,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 			sama7g5_plls[i].c)); | 			sama7g5_plls[i].c)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Register MCK0 clock. */ | 	/* Register MCK0_PRES clock. */ | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_MAINCK]; | 	p[1] = clk_names[ID_MAINCK]; | ||||||
| 	p[2] = clk_names[ID_PLL_CPU_DIV]; | 	p[2] = clk_names[ID_PLL_CPU_DIV]; | ||||||
|  | @ -1221,15 +1225,19 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); | ||||||
| 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2, | 	prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2, | ||||||
| 			  fail); | 			  fail); | ||||||
| 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0), | 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_PRES), | ||||||
| 		at91_clk_register_master(base, clk_names[ID_MCK0], p, | 		at91_clk_register_master_pres(base, clk_names[ID_MCK0_PRES], p, | ||||||
| 		4, &mck0_layout, &mck0_characteristics, tmpclkmux)); | 		4, &mck0_layout, &mck0_characteristics, tmpclkmux)); | ||||||
| 
 | 
 | ||||||
|  | 	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV), | ||||||
|  | 		at91_clk_register_master_div(base, clk_names[ID_MCK0_DIV], | ||||||
|  | 		clk_names[ID_MCK0_PRES], &mck0_layout, &mck0_characteristics)); | ||||||
|  | 
 | ||||||
| 	/* Register MCK1-4 clocks. */ | 	/* Register MCK1-4 clocks. */ | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_TD_SLCK]; | 	p[1] = clk_names[ID_TD_SLCK]; | ||||||
| 	p[2] = clk_names[ID_MAINCK]; | 	p[2] = clk_names[ID_MAINCK]; | ||||||
| 	p[3] = clk_names[ID_MCK0]; | 	p[3] = clk_names[ID_MCK0_DIV]; | ||||||
| 	m[0] = 0; | 	m[0] = 0; | ||||||
| 	m[1] = 1; | 	m[1] = 1; | ||||||
| 	m[2] = 2; | 	m[2] = 2; | ||||||
|  | @ -1237,7 +1245,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | ||||||
| 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | ||||||
| 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); | ||||||
| 	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { | 	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { | ||||||
| 		for (j = 0; j < sama7g5_mckx[i].ep_count; j++) { | 		for (j = 0; j < sama7g5_mckx[i].ep_count; j++) { | ||||||
| 			p[4 + j] = sama7g5_mckx[i].ep[j]; | 			p[4 + j] = sama7g5_mckx[i].ep[j]; | ||||||
|  | @ -1267,7 +1275,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_TD_SLCK]; | 	p[1] = clk_names[ID_TD_SLCK]; | ||||||
| 	p[2] = clk_names[ID_MAINCK]; | 	p[2] = clk_names[ID_MAINCK]; | ||||||
| 	p[3] = clk_names[ID_MCK0]; | 	p[3] = clk_names[ID_MCK0_DIV]; | ||||||
| 	p[4] = clk_names[ID_PLL_SYS_DIV]; | 	p[4] = clk_names[ID_PLL_SYS_DIV]; | ||||||
| 	p[5] = clk_names[ID_PLL_DDR_DIV]; | 	p[5] = clk_names[ID_PLL_DDR_DIV]; | ||||||
| 	p[6] = clk_names[ID_PLL_IMG_DIV]; | 	p[6] = clk_names[ID_PLL_IMG_DIV]; | ||||||
|  | @ -1277,7 +1285,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | ||||||
| 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | ||||||
| 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); | ||||||
| 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); | 	cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); | ||||||
| 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV); | 	cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV); | ||||||
| 	cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV); | 	cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV); | ||||||
|  | @ -1315,7 +1323,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	p[0] = clk_names[ID_MD_SLCK]; | 	p[0] = clk_names[ID_MD_SLCK]; | ||||||
| 	p[1] = clk_names[ID_TD_SLCK]; | 	p[1] = clk_names[ID_TD_SLCK]; | ||||||
| 	p[2] = clk_names[ID_MAINCK]; | 	p[2] = clk_names[ID_MAINCK]; | ||||||
| 	p[3] = clk_names[ID_MCK0]; | 	p[3] = clk_names[ID_MCK0_DIV]; | ||||||
| 	m[0] = 0; | 	m[0] = 0; | ||||||
| 	m[1] = 1; | 	m[1] = 1; | ||||||
| 	m[2] = 2; | 	m[2] = 2; | ||||||
|  | @ -1323,7 +1331,7 @@ static int sama7g5_clk_probe(struct udevice *dev) | ||||||
| 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | 	cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); | ||||||
| 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | 	cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); | ||||||
| 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | 	cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); | ||||||
| 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0); | 	cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); | ||||||
| 	for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { | 	for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { | ||||||
| 		for (j = 0; j < sama7g5_gck[i].ep_count; j++) { | 		for (j = 0; j < sama7g5_gck[i].ep_count; j++) { | ||||||
| 			p[4 + j] = sama7g5_gck[i].ep[j]; | 			p[4 + j] = sama7g5_gck[i].ep[j]; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue