brintos

brintos / linux-shallow public Read only

0
0
Text · 20.8 KiB · cbb8b22 Raw
947 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * SAM9X7 PMC code.4 *5 * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries6 *7 * Author: Varshini Rajendran <varshini.rajendran@microchip.com>8 *9 */10#include <linux/clk.h>11#include <linux/clk-provider.h>12#include <linux/mfd/syscon.h>13#include <linux/slab.h>14 15#include <dt-bindings/clock/at91.h>16 17#include "pmc.h"18 19static DEFINE_SPINLOCK(pmc_pll_lock);20static DEFINE_SPINLOCK(mck_lock);21 22/**23 * enum pll_ids - PLL clocks identifiers24 * @PLL_ID_PLLA:	PLLA identifier25 * @PLL_ID_UPLL:	UPLL identifier26 * @PLL_ID_AUDIO:	Audio PLL identifier27 * @PLL_ID_LVDS:	LVDS PLL identifier28 * @PLL_ID_PLLA_DIV2:	PLLA DIV2 identifier29 * @PLL_ID_MAX:		Max PLL Identifier30 */31enum pll_ids {32	PLL_ID_PLLA,33	PLL_ID_UPLL,34	PLL_ID_AUDIO,35	PLL_ID_LVDS,36	PLL_ID_PLLA_DIV2,37	PLL_ID_MAX,38};39 40/**41 * enum pll_type - PLL type identifiers42 * @PLL_TYPE_FRAC:	fractional PLL identifier43 * @PLL_TYPE_DIV:	divider PLL identifier44 */45enum pll_type {46	PLL_TYPE_FRAC,47	PLL_TYPE_DIV,48};49 50static const struct clk_master_characteristics mck_characteristics = {51	.output = { .min = 32000000, .max = 266666667 },52	.divisors = { 1, 2, 4, 3, 5},53	.have_div3_pres = 1,54};55 56static const struct clk_master_layout sam9x7_master_layout = {57	.mask = 0x373,58	.pres_shift = 4,59	.offset = 0x28,60};61 62/* Fractional PLL core output range. */63static const struct clk_range plla_core_outputs[] = {64	{ .min = 375000000, .max = 1600000000 },65};66 67static const struct clk_range upll_core_outputs[] = {68	{ .min = 600000000, .max = 1200000000 },69};70 71static const struct clk_range lvdspll_core_outputs[] = {72	{ .min = 400000000, .max = 800000000 },73};74 75static const struct clk_range audiopll_core_outputs[] = {76	{ .min = 400000000, .max = 800000000 },77};78 79static const struct clk_range plladiv2_core_outputs[] = {80	{ .min = 375000000, .max = 1600000000 },81};82 83/* Fractional PLL output range. */84static const struct clk_range plla_outputs[] = {85	{ .min = 732421, .max = 800000000 },86};87 88static const struct clk_range upll_outputs[] = {89	{ .min = 300000000, .max = 600000000 },90};91 92static const struct clk_range lvdspll_outputs[] = {93	{ .min = 10000000, .max = 800000000 },94};95 96static const struct clk_range audiopll_outputs[] = {97	{ .min = 10000000, .max = 800000000 },98};99 100static const struct clk_range plladiv2_outputs[] = {101	{ .min = 366210, .max = 400000000 },102};103 104/* PLL characteristics. */105static const struct clk_pll_characteristics plla_characteristics = {106	.input = { .min = 20000000, .max = 50000000 },107	.num_output = ARRAY_SIZE(plla_outputs),108	.output = plla_outputs,109	.core_output = plla_core_outputs,110};111 112static const struct clk_pll_characteristics upll_characteristics = {113	.input = { .min = 20000000, .max = 50000000 },114	.num_output = ARRAY_SIZE(upll_outputs),115	.output = upll_outputs,116	.core_output = upll_core_outputs,117	.upll = true,118};119 120static const struct clk_pll_characteristics lvdspll_characteristics = {121	.input = { .min = 20000000, .max = 50000000 },122	.num_output = ARRAY_SIZE(lvdspll_outputs),123	.output = lvdspll_outputs,124	.core_output = lvdspll_core_outputs,125};126 127static const struct clk_pll_characteristics audiopll_characteristics = {128	.input = { .min = 20000000, .max = 50000000 },129	.num_output = ARRAY_SIZE(audiopll_outputs),130	.output = audiopll_outputs,131	.core_output = audiopll_core_outputs,132};133 134static const struct clk_pll_characteristics plladiv2_characteristics = {135	.input = { .min = 20000000, .max = 50000000 },136	.num_output = ARRAY_SIZE(plladiv2_outputs),137	.output = plladiv2_outputs,138	.core_output = plladiv2_core_outputs,139};140 141/* Layout for fractional PLL ID PLLA. */142static const struct clk_pll_layout plla_frac_layout = {143	.mul_mask = GENMASK(31, 24),144	.frac_mask = GENMASK(21, 0),145	.mul_shift = 24,146	.frac_shift = 0,147	.div2 = 1,148};149 150/* Layout for fractional PLLs. */151static const struct clk_pll_layout pll_frac_layout = {152	.mul_mask = GENMASK(31, 24),153	.frac_mask = GENMASK(21, 0),154	.mul_shift = 24,155	.frac_shift = 0,156};157 158/* Layout for DIV PLLs. */159static const struct clk_pll_layout pll_divpmc_layout = {160	.div_mask = GENMASK(7, 0),161	.endiv_mask = BIT(29),162	.div_shift = 0,163	.endiv_shift = 29,164};165 166/* Layout for DIV PLL ID PLLADIV2. */167static const struct clk_pll_layout plladiv2_divpmc_layout = {168	.div_mask = GENMASK(7, 0),169	.endiv_mask = BIT(29),170	.div_shift = 0,171	.endiv_shift = 29,172	.div2 = 1,173};174 175/* Layout for DIVIO dividers. */176static const struct clk_pll_layout pll_divio_layout = {177	.div_mask	= GENMASK(19, 12),178	.endiv_mask	= BIT(30),179	.div_shift	= 12,180	.endiv_shift	= 30,181};182 183/*184 * PLL clocks description185 * @n:		clock name186 * @p:		clock parent187 * @l:		clock layout188 * @t:		clock type189 * @c:		pll characteristics190 * @f:		clock flags191 * @eid:	export index in sam9x7->chws[] array192 */193static const struct {194	const char *n;195	const char *p;196	const struct clk_pll_layout *l;197	u8 t;198	const struct clk_pll_characteristics *c;199	unsigned long f;200	u8 eid;201} sam9x7_plls[][3] = {202	[PLL_ID_PLLA] = {203		{204			.n = "plla_fracck",205			.p = "mainck",206			.l = &plla_frac_layout,207			.t = PLL_TYPE_FRAC,208			/*209			 * This feeds plla_divpmcck which feeds CPU. It should210			 * not be disabled.211			 */212			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,213			.c = &plla_characteristics,214		},215 216		{217			.n = "plla_divpmcck",218			.p = "plla_fracck",219			.l = &pll_divpmc_layout,220			.t = PLL_TYPE_DIV,221			/* This feeds CPU. It should not be disabled */222			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,223			.eid = PMC_PLLACK,224			.c = &plla_characteristics,225		},226	},227 228	[PLL_ID_UPLL] = {229		{230			.n = "upll_fracck",231			.p = "main_osc",232			.l = &pll_frac_layout,233			.t = PLL_TYPE_FRAC,234			.f = CLK_SET_RATE_GATE,235			.c = &upll_characteristics,236		},237 238		{239			.n = "upll_divpmcck",240			.p = "upll_fracck",241			.l = &pll_divpmc_layout,242			.t = PLL_TYPE_DIV,243			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |244			     CLK_SET_RATE_PARENT,245			.eid = PMC_UTMI,246			.c = &upll_characteristics,247		},248	},249 250	[PLL_ID_AUDIO] = {251		{252			.n = "audiopll_fracck",253			.p = "main_osc",254			.l = &pll_frac_layout,255			.f = CLK_SET_RATE_GATE,256			.c = &audiopll_characteristics,257			.t = PLL_TYPE_FRAC,258		},259 260		{261			.n = "audiopll_divpmcck",262			.p = "audiopll_fracck",263			.l = &pll_divpmc_layout,264			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |265			     CLK_SET_RATE_PARENT,266			.c = &audiopll_characteristics,267			.eid = PMC_AUDIOPMCPLL,268			.t = PLL_TYPE_DIV,269		},270 271		{272			.n = "audiopll_diviock",273			.p = "audiopll_fracck",274			.l = &pll_divio_layout,275			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |276			     CLK_SET_RATE_PARENT,277			.c = &audiopll_characteristics,278			.eid = PMC_AUDIOIOPLL,279			.t = PLL_TYPE_DIV,280		},281	},282 283	[PLL_ID_LVDS] = {284		{285			.n = "lvdspll_fracck",286			.p = "main_osc",287			.l = &pll_frac_layout,288			.f = CLK_SET_RATE_GATE,289			.c = &lvdspll_characteristics,290			.t = PLL_TYPE_FRAC,291		},292 293		{294			.n = "lvdspll_divpmcck",295			.p = "lvdspll_fracck",296			.l = &pll_divpmc_layout,297			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |298			     CLK_SET_RATE_PARENT,299			.c = &lvdspll_characteristics,300			.eid = PMC_LVDSPLL,301			.t = PLL_TYPE_DIV,302		},303	},304 305	[PLL_ID_PLLA_DIV2] = {306		{307			.n = "plla_div2pmcck",308			.p = "plla_fracck",309			.l = &plladiv2_divpmc_layout,310			/*311			 * This may feed critical parts of the system like timers.312			 * It should not be disabled.313			 */314			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,315			.c = &plladiv2_characteristics,316			.eid = PMC_PLLADIV2,317			.t = PLL_TYPE_DIV,318		},319	},320};321 322static const struct clk_programmable_layout sam9x7_programmable_layout = {323	.pres_mask = 0xff,324	.pres_shift = 8,325	.css_mask = 0x1f,326	.have_slck_mck = 0,327	.is_pres_direct = 1,328};329 330static const struct clk_pcr_layout sam9x7_pcr_layout = {331	.offset = 0x88,332	.cmd = BIT(31),333	.gckcss_mask = GENMASK(12, 8),334	.pid_mask = GENMASK(6, 0),335};336 337static const struct {338	char *n;339	char *p;340	u8 id;341	unsigned long flags;342} sam9x7_systemck[] = {343	/*344	 * ddrck feeds DDR controller and is enabled by bootloader thus we need345	 * to keep it enabled in case there is no Linux consumer for it.346	 */347	{ .n = "ddrck",		.p = "masterck_div",	.id = 2,	.flags = CLK_IS_CRITICAL },348	{ .n = "uhpck",		.p = "usbck",		.id = 6 },349	{ .n = "pck0",		.p = "prog0",		.id = 8 },350	{ .n = "pck1",		.p = "prog1",		.id = 9 },351};352 353/*354 * Peripheral clocks description355 * @n:		clock name356 * @f:		clock flags357 * @id:		peripheral id358 */359static const struct {360	char *n;361	unsigned long f;362	u8 id;363} sam9x7_periphck[] = {364	{ .n = "pioA_clk",	.id = 2, },365	{ .n = "pioB_clk",	.id = 3, },366	{ .n = "pioC_clk",	.id = 4, },367	{ .n = "flex0_clk",	.id = 5, },368	{ .n = "flex1_clk",	.id = 6, },369	{ .n = "flex2_clk",	.id = 7, },370	{ .n = "flex3_clk",	.id = 8, },371	{ .n = "flex6_clk",	.id = 9, },372	{ .n = "flex7_clk",	.id = 10, },373	{ .n = "flex8_clk",	.id = 11, },374	{ .n = "sdmmc0_clk",	.id = 12, },375	{ .n = "flex4_clk",	.id = 13, },376	{ .n = "flex5_clk",	.id = 14, },377	{ .n = "flex9_clk",	.id = 15, },378	{ .n = "flex10_clk",	.id = 16, },379	{ .n = "tcb0_clk",	.id = 17, },380	{ .n = "pwm_clk",	.id = 18, },381	{ .n = "adc_clk",	.id = 19, },382	{ .n = "dma0_clk",	.id = 20, },383	{ .n = "uhphs_clk",	.id = 22, },384	{ .n = "udphs_clk",	.id = 23, },385	{ .n = "macb0_clk",	.id = 24, },386	{ .n = "lcd_clk",	.id = 25, },387	{ .n = "sdmmc1_clk",	.id = 26, },388	{ .n = "ssc_clk",	.id = 28, },389	{ .n = "can0_clk",	.id = 29, },390	{ .n = "can1_clk",	.id = 30, },391	{ .n = "flex11_clk",	.id = 32, },392	{ .n = "flex12_clk",	.id = 33, },393	{ .n = "i2s_clk",	.id = 34, },394	{ .n = "qspi_clk",	.id = 35, },395	{ .n = "gfx2d_clk",	.id = 36, },396	{ .n = "pit64b0_clk",	.id = 37, },397	{ .n = "trng_clk",	.id = 38, },398	{ .n = "aes_clk",	.id = 39, },399	{ .n = "tdes_clk",	.id = 40, },400	{ .n = "sha_clk",	.id = 41, },401	{ .n = "classd_clk",	.id = 42, },402	{ .n = "isi_clk",	.id = 43, },403	{ .n = "pioD_clk",	.id = 44, },404	{ .n = "tcb1_clk",	.id = 45, },405	{ .n = "dbgu_clk",	.id = 47, },406	/*407	 * mpddr_clk feeds DDR controller and is enabled by bootloader thus we408	 * need to keep it enabled in case there is no Linux consumer for it.409	 */410	{ .n = "mpddr_clk",	.id = 49,	.f = CLK_IS_CRITICAL },411	{ .n = "csi2dc_clk",	.id = 52, },412	{ .n = "csi4l_clk",	.id = 53, },413	{ .n = "dsi4l_clk",	.id = 54, },414	{ .n = "lvdsc_clk",	.id = 56, },415	{ .n = "pit64b1_clk",	.id = 58, },416	{ .n = "puf_clk",	.id = 59, },417	{ .n = "gmactsu_clk",	.id = 67, },418};419 420/*421 * Generic clock description422 * @n:			clock name423 * @pp:			PLL parents424 * @pp_mux_table:	PLL parents mux table425 * @r:			clock output range426 * @pp_chg_id:		id in parent array of changeable PLL parent427 * @pp_count:		PLL parents count428 * @id:			clock id429 */430static const struct {431	const char *n;432	const char *pp[8];433	const char pp_mux_table[8];434	struct clk_range r;435	int pp_chg_id;436	u8 pp_count;437	u8 id;438} sam9x7_gck[] = {439	{440		.n = "flex0_gclk",441		.id = 5,442		.pp = { "plla_div2pmcck", },443		.pp_mux_table = { 8, },444		.pp_count = 1,445		.pp_chg_id = INT_MIN,446	},447 448	{449		.n = "flex1_gclk",450		.id = 6,451		.pp = { "plla_div2pmcck", },452		.pp_mux_table = { 8, },453		.pp_count = 1,454		.pp_chg_id = INT_MIN,455	},456 457	{458		.n = "flex2_gclk",459		.id = 7,460		.pp = { "plla_div2pmcck", },461		.pp_mux_table = { 8, },462		.pp_count = 1,463		.pp_chg_id = INT_MIN,464	},465 466	{467		.n = "flex3_gclk",468		.id = 8,469		.pp = { "plla_div2pmcck", },470		.pp_mux_table = { 8, },471		.pp_count = 1,472		.pp_chg_id = INT_MIN,473	},474 475	{476		.n = "flex6_gclk",477		.id = 9,478		.pp = { "plla_div2pmcck", },479		.pp_mux_table = { 8, },480		.pp_count = 1,481		.pp_chg_id = INT_MIN,482	},483 484	{485		.n = "flex7_gclk",486		.id = 10,487		.pp = { "plla_div2pmcck", },488		.pp_mux_table = { 8, },489		.pp_count = 1,490		.pp_chg_id = INT_MIN,491	},492 493	{494		.n = "flex8_gclk",495		.id = 11,496		.pp = { "plla_div2pmcck", },497		.pp_mux_table = { 8, },498		.pp_count = 1,499		.pp_chg_id = INT_MIN,500	},501 502	{503		.n = "sdmmc0_gclk",504		.id = 12,505		.r = { .max = 105000000 },506		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },507		.pp_mux_table = { 6, 8, },508		.pp_count = 2,509		.pp_chg_id = INT_MIN,510	},511 512	{513		.n = "flex4_gclk",514		.id = 13,515		.pp = { "plla_div2pmcck", },516		.pp_mux_table = { 8, },517		.pp_count = 1,518		.pp_chg_id = INT_MIN,519	},520 521	{522		.n = "flex5_gclk",523		.id = 14,524		.pp = { "plla_div2pmcck", },525		.pp_mux_table = { 8, },526		.pp_count = 1,527		.pp_chg_id = INT_MIN,528	},529 530	{531		.n = "flex9_gclk",532		.id = 15,533		.pp = { "plla_div2pmcck", },534		.pp_mux_table = { 8, },535		.pp_count = 1,536		.pp_chg_id = INT_MIN,537	},538 539	{540		.n = "flex10_gclk",541		.id = 16,542		.pp = { "plla_div2pmcck", },543		.pp_mux_table = { 8, },544		.pp_count = 1,545		.pp_chg_id = INT_MIN,546	},547 548	{549		.n = "tcb0_gclk",550		.id = 17,551		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },552		.pp_mux_table = { 6, 8, },553		.pp_count = 2,554		.pp_chg_id = INT_MIN,555	},556 557	{558		.n = "adc_gclk",559		.id = 19,560		.pp = { "upll_divpmcck", "plla_div2pmcck", },561		.pp_mux_table = { 5, 8, },562		.pp_count = 2,563		.pp_chg_id = INT_MIN,564	},565 566	{567		.n = "lcd_gclk",568		.id = 25,569		.r = { .max = 75000000 },570		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },571		.pp_mux_table = { 6, 8, },572		.pp_count = 2,573		.pp_chg_id = INT_MIN,574	},575 576	{577		.n = "sdmmc1_gclk",578		.id = 26,579		.r = { .max = 105000000 },580		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },581		.pp_mux_table = { 6, 8, },582		.pp_count = 2,583		.pp_chg_id = INT_MIN,584	},585 586	{587		.n = "mcan0_gclk",588		.id = 29,589		.r = { .max = 80000000 },590		.pp = { "upll_divpmcck", "plla_div2pmcck", },591		.pp_mux_table = { 5, 8, },592		.pp_count = 2,593		.pp_chg_id = INT_MIN,594	},595 596	{597		.n = "mcan1_gclk",598		.id = 30,599		.r = { .max = 80000000 },600		.pp = { "upll_divpmcck", "plla_div2pmcck", },601		.pp_mux_table = { 5, 8, },602		.pp_count = 2,603		.pp_chg_id = INT_MIN,604	},605 606	{607		.n = "flex11_gclk",608		.id = 32,609		.pp = { "plla_div2pmcck", },610		.pp_mux_table = { 8, },611		.pp_count = 1,612		.pp_chg_id = INT_MIN,613	},614 615	{616		.n = "flex12_gclk",617		.id = 33,618		.pp = { "plla_div2pmcck", },619		.pp_mux_table = { 8, },620		.pp_count = 1,621		.pp_chg_id = INT_MIN,622	},623 624	{625		.n = "i2s_gclk",626		.id = 34,627		.r = { .max = 100000000 },628		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },629		.pp_mux_table = { 6, 8, },630		.pp_count = 2,631		.pp_chg_id = INT_MIN,632	},633 634	{635		.n = "qspi_gclk",636		.id = 35,637		.r = { .max = 200000000 },638		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },639		.pp_mux_table = { 6, 8, },640		.pp_count = 2,641		.pp_chg_id = INT_MIN,642	},643 644	{645		.n = "pit64b0_gclk",646		.id = 37,647		.pp = { "plla_div2pmcck", },648		.pp_mux_table = { 8, },649		.pp_count = 1,650		.pp_chg_id = INT_MIN,651	},652 653	{654		.n = "classd_gclk",655		.id = 42,656		.r = { .max = 100000000 },657		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },658		.pp_mux_table = { 6, 8, },659		.pp_count = 2,660		.pp_chg_id = INT_MIN,661	},662 663	{664		.n = "tcb1_gclk",665		.id = 45,666		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },667		.pp_mux_table = { 6, 8, },668		.pp_count = 2,669		.pp_chg_id = INT_MIN,670	},671 672	{673		.n = "dbgu_gclk",674		.id = 47,675		.pp = { "plla_div2pmcck", },676		.pp_mux_table = { 8, },677		.pp_count = 1,678		.pp_chg_id = INT_MIN,679	},680 681	{682		.n = "mipiphy_gclk",683		.id = 55,684		.r = { .max = 27000000 },685		.pp = { "plla_div2pmcck", },686		.pp_mux_table = { 8, },687		.pp_count = 1,688		.pp_chg_id = INT_MIN,689	},690 691	{692		.n = "pit64b1_gclk",693		.id = 58,694		.pp = { "plla_div2pmcck", },695		.pp_mux_table = { 8, },696		.pp_count = 1,697		.pp_chg_id = INT_MIN,698	},699 700	{701		.n = "gmac_gclk",702		.id = 67,703		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },704		.pp_mux_table = { 6, 8, },705		.pp_count = 2,706		.pp_chg_id = INT_MIN,707	},708};709 710static void __init sam9x7_pmc_setup(struct device_node *np)711{712	struct clk_range range = CLK_RANGE(0, 0);713	const char *td_slck_name, *md_slck_name, *mainxtal_name;714	struct pmc_data *sam9x7_pmc;715	const char *parent_names[9];716	void **clk_mux_buffer = NULL;717	int clk_mux_buffer_size = 0;718	struct clk_hw *main_osc_hw;719	struct regmap *regmap;720	struct clk_hw *hw;721	int i, j;722 723	i = of_property_match_string(np, "clock-names", "td_slck");724	if (i < 0)725		return;726 727	td_slck_name = of_clk_get_parent_name(np, i);728 729	i = of_property_match_string(np, "clock-names", "md_slck");730	if (i < 0)731		return;732 733	md_slck_name = of_clk_get_parent_name(np, i);734 735	i = of_property_match_string(np, "clock-names", "main_xtal");736	if (i < 0)737		return;738	mainxtal_name = of_clk_get_parent_name(np, i);739 740	regmap = device_node_to_regmap(np);741	if (IS_ERR(regmap))742		return;743 744	sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1,745				       nck(sam9x7_systemck),746				       nck(sam9x7_periphck),747				       nck(sam9x7_gck), 8);748	if (!sam9x7_pmc)749		return;750 751	clk_mux_buffer = kmalloc(sizeof(void *) *752				 (ARRAY_SIZE(sam9x7_gck)),753				 GFP_KERNEL);754	if (!clk_mux_buffer)755		goto err_free;756 757	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,758					   50000000);759	if (IS_ERR(hw))760		goto err_free;761 762	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);763	if (IS_ERR(hw))764		goto err_free;765	main_osc_hw = hw;766 767	parent_names[0] = "main_rc_osc";768	parent_names[1] = "main_osc";769	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);770	if (IS_ERR(hw))771		goto err_free;772 773	sam9x7_pmc->chws[PMC_MAIN] = hw;774 775	for (i = 0; i < PLL_ID_MAX; i++) {776		for (j = 0; j < 3; j++) {777			struct clk_hw *parent_hw;778 779			if (!sam9x7_plls[i][j].n)780				continue;781 782			switch (sam9x7_plls[i][j].t) {783			case PLL_TYPE_FRAC:784				if (!strcmp(sam9x7_plls[i][j].p, "mainck"))785					parent_hw = sam9x7_pmc->chws[PMC_MAIN];786				else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))787					parent_hw = main_osc_hw;788				else789					parent_hw = __clk_get_hw(of_clk_get_by_name790								 (np, sam9x7_plls[i][j].p));791 792				hw = sam9x60_clk_register_frac_pll(regmap,793								   &pmc_pll_lock,794								   sam9x7_plls[i][j].n,795								   sam9x7_plls[i][j].p,796								   parent_hw, i,797								   sam9x7_plls[i][j].c,798								   sam9x7_plls[i][j].l,799								   sam9x7_plls[i][j].f);800				break;801 802			case PLL_TYPE_DIV:803				hw = sam9x60_clk_register_div_pll(regmap,804								  &pmc_pll_lock,805								  sam9x7_plls[i][j].n,806								  sam9x7_plls[i][j].p, NULL, i,807								  sam9x7_plls[i][j].c,808								  sam9x7_plls[i][j].l,809								  sam9x7_plls[i][j].f, 0);810				break;811 812			default:813				continue;814			}815 816			if (IS_ERR(hw))817				goto err_free;818 819			if (sam9x7_plls[i][j].eid)820				sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;821		}822	}823 824	parent_names[0] = md_slck_name;825	parent_names[1] = "mainck";826	parent_names[2] = "plla_divpmcck";827	parent_names[3] = "upll_divpmcck";828	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,829					   parent_names, NULL, &sam9x7_master_layout,830					   &mck_characteristics, &mck_lock);831	if (IS_ERR(hw))832		goto err_free;833 834	hw = at91_clk_register_master_div(regmap, "masterck_div",835					  "masterck_pres", NULL, &sam9x7_master_layout,836					  &mck_characteristics, &mck_lock,837					  CLK_SET_RATE_GATE, 0);838	if (IS_ERR(hw))839		goto err_free;840 841	sam9x7_pmc->chws[PMC_MCK] = hw;842 843	parent_names[0] = "plla_divpmcck";844	parent_names[1] = "upll_divpmcck";845	parent_names[2] = "main_osc";846	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);847	if (IS_ERR(hw))848		goto err_free;849 850	parent_names[0] = md_slck_name;851	parent_names[1] = td_slck_name;852	parent_names[2] = "mainck";853	parent_names[3] = "masterck_div";854	parent_names[4] = "plla_divpmcck";855	parent_names[5] = "upll_divpmcck";856	parent_names[6] = "audiopll_divpmcck";857	for (i = 0; i < 2; i++) {858		char name[6];859 860		snprintf(name, sizeof(name), "prog%d", i);861 862		hw = at91_clk_register_programmable(regmap, name,863						    parent_names, NULL, 7, i,864						    &sam9x7_programmable_layout,865						    NULL);866		if (IS_ERR(hw))867			goto err_free;868 869		sam9x7_pmc->pchws[i] = hw;870	}871 872	for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {873		hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,874					      sam9x7_systemck[i].p, NULL,875					      sam9x7_systemck[i].id,876					      sam9x7_systemck[i].flags);877		if (IS_ERR(hw))878			goto err_free;879 880		sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw;881	}882 883	for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {884		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,885							 &sam9x7_pcr_layout,886							 sam9x7_periphck[i].n,887							 "masterck_div", NULL,888							 sam9x7_periphck[i].id,889							 &range, INT_MIN,890							 sam9x7_periphck[i].f);891		if (IS_ERR(hw))892			goto err_free;893 894		sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;895	}896 897	parent_names[0] = md_slck_name;898	parent_names[1] = td_slck_name;899	parent_names[2] = "mainck";900	parent_names[3] = "masterck_div";901	for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {902		u8 num_parents = 4 + sam9x7_gck[i].pp_count;903		u32 *mux_table;904 905		mux_table = kmalloc_array(num_parents, sizeof(*mux_table),906					  GFP_KERNEL);907		if (!mux_table)908			goto err_free;909 910		PMC_INIT_TABLE(mux_table, 4);911		PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,912			       sam9x7_gck[i].pp_count);913		PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,914			       sam9x7_gck[i].pp_count);915 916		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,917						 &sam9x7_pcr_layout,918						 sam9x7_gck[i].n,919						 parent_names, NULL, mux_table,920						 num_parents,921						 sam9x7_gck[i].id,922						 &sam9x7_gck[i].r,923						 sam9x7_gck[i].pp_chg_id);924		if (IS_ERR(hw))925			goto err_free;926 927		sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw;928		clk_mux_buffer[clk_mux_buffer_size++] = mux_table;929	}930 931	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);932	kfree(clk_mux_buffer);933 934	return;935 936err_free:937	if (clk_mux_buffer) {938		for (i = 0; i < clk_mux_buffer_size; i++)939			kfree(clk_mux_buffer[i]);940		kfree(clk_mux_buffer);941	}942	kfree(sam9x7_pmc);943}944 945/* Some clks are used for a clocksource */946CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup);947