cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sama7g5.c (30442B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * SAMA7G5 PMC code.
      4 *
      5 * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
      6 *
      7 * Author: Claudiu Beznea <claudiu.beznea@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
     19#define SAMA7G5_INIT_TABLE(_table, _count)		\
     20	do {						\
     21		u8 _i;					\
     22		for (_i = 0; _i < (_count); _i++)	\
     23			(_table)[_i] = _i;		\
     24	} while (0)
     25
     26#define SAMA7G5_FILL_TABLE(_to, _from, _count)		\
     27	do {						\
     28		u8 _i;					\
     29		for (_i = 0; _i < (_count); _i++) {	\
     30			(_to)[_i] = (_from)[_i];	\
     31		}					\
     32	} while (0)
     33
     34static DEFINE_SPINLOCK(pmc_pll_lock);
     35static DEFINE_SPINLOCK(pmc_mck0_lock);
     36static DEFINE_SPINLOCK(pmc_mckX_lock);
     37
     38/*
     39 * PLL clocks identifiers
     40 * @PLL_ID_CPU:		CPU PLL identifier
     41 * @PLL_ID_SYS:		System PLL identifier
     42 * @PLL_ID_DDR:		DDR PLL identifier
     43 * @PLL_ID_IMG:		Image subsystem PLL identifier
     44 * @PLL_ID_BAUD:	Baud PLL identifier
     45 * @PLL_ID_AUDIO:	Audio PLL identifier
     46 * @PLL_ID_ETH:		Ethernet PLL identifier
     47 */
     48enum pll_ids {
     49	PLL_ID_CPU,
     50	PLL_ID_SYS,
     51	PLL_ID_DDR,
     52	PLL_ID_IMG,
     53	PLL_ID_BAUD,
     54	PLL_ID_AUDIO,
     55	PLL_ID_ETH,
     56	PLL_ID_MAX,
     57};
     58
     59/*
     60 * PLL type identifiers
     61 * @PLL_TYPE_FRAC:	fractional PLL identifier
     62 * @PLL_TYPE_DIV:	divider PLL identifier
     63 */
     64enum pll_type {
     65	PLL_TYPE_FRAC,
     66	PLL_TYPE_DIV,
     67};
     68
     69/* Layout for fractional PLLs. */
     70static const struct clk_pll_layout pll_layout_frac = {
     71	.mul_mask	= GENMASK(31, 24),
     72	.frac_mask	= GENMASK(21, 0),
     73	.mul_shift	= 24,
     74	.frac_shift	= 0,
     75};
     76
     77/* Layout for DIVPMC dividers. */
     78static const struct clk_pll_layout pll_layout_divpmc = {
     79	.div_mask	= GENMASK(7, 0),
     80	.endiv_mask	= BIT(29),
     81	.div_shift	= 0,
     82	.endiv_shift	= 29,
     83};
     84
     85/* Layout for DIVIO dividers. */
     86static const struct clk_pll_layout pll_layout_divio = {
     87	.div_mask	= GENMASK(19, 12),
     88	.endiv_mask	= BIT(30),
     89	.div_shift	= 12,
     90	.endiv_shift	= 30,
     91};
     92
     93/*
     94 * CPU PLL output range.
     95 * Notice: The upper limit has been setup to 1000000002 due to hardware
     96 * block which cannot output exactly 1GHz.
     97 */
     98static const struct clk_range cpu_pll_outputs[] = {
     99	{ .min = 2343750, .max = 1000000002 },
    100};
    101
    102/* PLL output range. */
    103static const struct clk_range pll_outputs[] = {
    104	{ .min = 2343750, .max = 1200000000 },
    105};
    106
    107/* CPU PLL characteristics. */
    108static const struct clk_pll_characteristics cpu_pll_characteristics = {
    109	.input = { .min = 12000000, .max = 50000000 },
    110	.num_output = ARRAY_SIZE(cpu_pll_outputs),
    111	.output = cpu_pll_outputs,
    112};
    113
    114/* PLL characteristics. */
    115static const struct clk_pll_characteristics pll_characteristics = {
    116	.input = { .min = 12000000, .max = 50000000 },
    117	.num_output = ARRAY_SIZE(pll_outputs),
    118	.output = pll_outputs,
    119};
    120
    121/*
    122 * PLL clocks description
    123 * @n:		clock name
    124 * @p:		clock parent
    125 * @l:		clock layout
    126 * @c:		clock characteristics
    127 * @t:		clock type
    128 * @f:		clock flags
    129 * @eid:	export index in sama7g5->chws[] array
    130 * @safe_div:	intermediate divider need to be set on PRE_RATE_CHANGE
    131 *		notification
    132 */
    133static const struct {
    134	const char *n;
    135	const char *p;
    136	const struct clk_pll_layout *l;
    137	const struct clk_pll_characteristics *c;
    138	unsigned long f;
    139	u8 t;
    140	u8 eid;
    141	u8 safe_div;
    142} sama7g5_plls[][PLL_ID_MAX] = {
    143	[PLL_ID_CPU] = {
    144		{ .n = "cpupll_fracck",
    145		  .p = "mainck",
    146		  .l = &pll_layout_frac,
    147		  .c = &cpu_pll_characteristics,
    148		  .t = PLL_TYPE_FRAC,
    149		   /*
    150		    * This feeds cpupll_divpmcck which feeds CPU. It should
    151		    * not be disabled.
    152		    */
    153		  .f = CLK_IS_CRITICAL, },
    154
    155		{ .n = "cpupll_divpmcck",
    156		  .p = "cpupll_fracck",
    157		  .l = &pll_layout_divpmc,
    158		  .c = &cpu_pll_characteristics,
    159		  .t = PLL_TYPE_DIV,
    160		   /* This feeds CPU. It should not be disabled. */
    161		  .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
    162		  .eid = PMC_CPUPLL,
    163		  /*
    164		   * Safe div=15 should be safe even for switching b/w 1GHz and
    165		   * 90MHz (frac pll might go up to 1.2GHz).
    166		   */
    167		  .safe_div = 15, },
    168	},
    169
    170	[PLL_ID_SYS] = {
    171		{ .n = "syspll_fracck",
    172		  .p = "mainck",
    173		  .l = &pll_layout_frac,
    174		  .c = &pll_characteristics,
    175		  .t = PLL_TYPE_FRAC,
    176		   /*
    177		    * This feeds syspll_divpmcck which may feed critical parts
    178		    * of the systems like timers. Therefore it should not be
    179		    * disabled.
    180		    */
    181		  .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, },
    182
    183		{ .n = "syspll_divpmcck",
    184		  .p = "syspll_fracck",
    185		  .l = &pll_layout_divpmc,
    186		  .c = &pll_characteristics,
    187		  .t = PLL_TYPE_DIV,
    188		   /*
    189		    * This may feed critical parts of the systems like timers.
    190		    * Therefore it should not be disabled.
    191		    */
    192		  .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
    193		  .eid = PMC_SYSPLL, },
    194	},
    195
    196	[PLL_ID_DDR] = {
    197		{ .n = "ddrpll_fracck",
    198		  .p = "mainck",
    199		  .l = &pll_layout_frac,
    200		  .c = &pll_characteristics,
    201		  .t = PLL_TYPE_FRAC,
    202		   /*
    203		    * This feeds ddrpll_divpmcck which feeds DDR. It should not
    204		    * be disabled.
    205		    */
    206		  .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, },
    207
    208		{ .n = "ddrpll_divpmcck",
    209		  .p = "ddrpll_fracck",
    210		  .l = &pll_layout_divpmc,
    211		  .c = &pll_characteristics,
    212		  .t = PLL_TYPE_DIV,
    213		   /* This feeds DDR. It should not be disabled. */
    214		  .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, },
    215	},
    216
    217	[PLL_ID_IMG] = {
    218		{ .n = "imgpll_fracck",
    219		  .p = "mainck",
    220		  .l = &pll_layout_frac,
    221		  .c = &pll_characteristics,
    222		  .t = PLL_TYPE_FRAC,
    223		  .f = CLK_SET_RATE_GATE, },
    224
    225		{ .n = "imgpll_divpmcck",
    226		  .p = "imgpll_fracck",
    227		  .l = &pll_layout_divpmc,
    228		  .c = &pll_characteristics,
    229		  .t = PLL_TYPE_DIV,
    230		  .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
    231		       CLK_SET_RATE_PARENT, },
    232	},
    233
    234	[PLL_ID_BAUD] = {
    235		{ .n = "baudpll_fracck",
    236		  .p = "mainck",
    237		  .l = &pll_layout_frac,
    238		  .c = &pll_characteristics,
    239		  .t = PLL_TYPE_FRAC,
    240		  .f = CLK_SET_RATE_GATE, },
    241
    242		{ .n = "baudpll_divpmcck",
    243		  .p = "baudpll_fracck",
    244		  .l = &pll_layout_divpmc,
    245		  .c = &pll_characteristics,
    246		  .t = PLL_TYPE_DIV,
    247		  .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
    248		       CLK_SET_RATE_PARENT, },
    249	},
    250
    251	[PLL_ID_AUDIO] = {
    252		{ .n = "audiopll_fracck",
    253		  .p = "main_xtal",
    254		  .l = &pll_layout_frac,
    255		  .c = &pll_characteristics,
    256		  .t = PLL_TYPE_FRAC,
    257		  .f = CLK_SET_RATE_GATE, },
    258
    259		{ .n = "audiopll_divpmcck",
    260		  .p = "audiopll_fracck",
    261		  .l = &pll_layout_divpmc,
    262		  .c = &pll_characteristics,
    263		  .t = PLL_TYPE_DIV,
    264		  .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
    265		       CLK_SET_RATE_PARENT,
    266		  .eid = PMC_AUDIOPMCPLL, },
    267
    268		{ .n = "audiopll_diviock",
    269		  .p = "audiopll_fracck",
    270		  .l = &pll_layout_divio,
    271		  .c = &pll_characteristics,
    272		  .t = PLL_TYPE_DIV,
    273		  .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
    274		       CLK_SET_RATE_PARENT,
    275		  .eid = PMC_AUDIOIOPLL, },
    276	},
    277
    278	[PLL_ID_ETH] = {
    279		{ .n = "ethpll_fracck",
    280		  .p = "main_xtal",
    281		  .l = &pll_layout_frac,
    282		  .c = &pll_characteristics,
    283		  .t = PLL_TYPE_FRAC,
    284		  .f = CLK_SET_RATE_GATE, },
    285
    286		{ .n = "ethpll_divpmcck",
    287		  .p = "ethpll_fracck",
    288		  .l = &pll_layout_divpmc,
    289		  .c = &pll_characteristics,
    290		  .t = PLL_TYPE_DIV,
    291		  .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
    292		       CLK_SET_RATE_PARENT, },
    293	},
    294};
    295
    296/*
    297 * Master clock (MCK[1..4]) description
    298 * @n:			clock name
    299 * @ep:			extra parents names array
    300 * @ep_chg_chg_id:	index in parents array that specifies the changeable
    301 *			parent
    302 * @ep_count:		extra parents count
    303 * @ep_mux_table:	mux table for extra parents
    304 * @id:			clock id
    305 * @eid:		export index in sama7g5->chws[] array
    306 * @c:			true if clock is critical and cannot be disabled
    307 */
    308static const struct {
    309	const char *n;
    310	const char *ep[4];
    311	int ep_chg_id;
    312	u8 ep_count;
    313	u8 ep_mux_table[4];
    314	u8 id;
    315	u8 eid;
    316	u8 c;
    317} sama7g5_mckx[] = {
    318	{ .n = "mck1",
    319	  .id = 1,
    320	  .ep = { "syspll_divpmcck", },
    321	  .ep_mux_table = { 5, },
    322	  .ep_count = 1,
    323	  .ep_chg_id = INT_MIN,
    324	  .eid = PMC_MCK1,
    325	  .c = 1, },
    326
    327	{ .n = "mck2",
    328	  .id = 2,
    329	  .ep = { "ddrpll_divpmcck", },
    330	  .ep_mux_table = { 6, },
    331	  .ep_count = 1,
    332	  .ep_chg_id = INT_MIN,
    333	  .c = 1, },
    334
    335	{ .n = "mck3",
    336	  .id = 3,
    337	  .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
    338	  .ep_mux_table = { 5, 6, 7, },
    339	  .ep_count = 3,
    340	  .ep_chg_id = 5, },
    341
    342	{ .n = "mck4",
    343	  .id = 4,
    344	  .ep = { "syspll_divpmcck", },
    345	  .ep_mux_table = { 5, },
    346	  .ep_count = 1,
    347	  .ep_chg_id = INT_MIN,
    348	  .c = 1, },
    349};
    350
    351/*
    352 * System clock description
    353 * @n:	clock name
    354 * @p:	clock parent name
    355 * @id: clock id
    356 */
    357static const struct {
    358	const char *n;
    359	const char *p;
    360	u8 id;
    361} sama7g5_systemck[] = {
    362	{ .n = "pck0",		.p = "prog0", .id = 8, },
    363	{ .n = "pck1",		.p = "prog1", .id = 9, },
    364	{ .n = "pck2",		.p = "prog2", .id = 10, },
    365	{ .n = "pck3",		.p = "prog3", .id = 11, },
    366	{ .n = "pck4",		.p = "prog4", .id = 12, },
    367	{ .n = "pck5",		.p = "prog5", .id = 13, },
    368	{ .n = "pck6",		.p = "prog6", .id = 14, },
    369	{ .n = "pck7",		.p = "prog7", .id = 15, },
    370};
    371
    372/* Mux table for programmable clocks. */
    373static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
    374
    375/*
    376 * Peripheral clock description
    377 * @n:		clock name
    378 * @p:		clock parent name
    379 * @r:		clock range values
    380 * @id:		clock id
    381 * @chgp:	index in parent array of the changeable parent
    382 */
    383static const struct {
    384	const char *n;
    385	const char *p;
    386	struct clk_range r;
    387	u8 chgp;
    388	u8 id;
    389} sama7g5_periphck[] = {
    390	{ .n = "pioA_clk",	.p = "mck0", .id = 11, },
    391	{ .n = "securam_clk",	.p = "mck0", .id = 18, },
    392	{ .n = "sfr_clk",	.p = "mck1", .id = 19, },
    393	{ .n = "hsmc_clk",	.p = "mck1", .id = 21, },
    394	{ .n = "xdmac0_clk",	.p = "mck1", .id = 22, },
    395	{ .n = "xdmac1_clk",	.p = "mck1", .id = 23, },
    396	{ .n = "xdmac2_clk",	.p = "mck1", .id = 24, },
    397	{ .n = "acc_clk",	.p = "mck1", .id = 25, },
    398	{ .n = "aes_clk",	.p = "mck1", .id = 27, },
    399	{ .n = "tzaesbasc_clk",	.p = "mck1", .id = 28, },
    400	{ .n = "asrc_clk",	.p = "mck1", .id = 30, .r = { .max = 200000000, }, },
    401	{ .n = "cpkcc_clk",	.p = "mck0", .id = 32, },
    402	{ .n = "csi_clk",	.p = "mck3", .id = 33, .r = { .max = 266000000, }, .chgp = 1, },
    403	{ .n = "csi2dc_clk",	.p = "mck3", .id = 34, .r = { .max = 266000000, }, .chgp = 1, },
    404	{ .n = "eic_clk",	.p = "mck1", .id = 37, },
    405	{ .n = "flex0_clk",	.p = "mck1", .id = 38, },
    406	{ .n = "flex1_clk",	.p = "mck1", .id = 39, },
    407	{ .n = "flex2_clk",	.p = "mck1", .id = 40, },
    408	{ .n = "flex3_clk",	.p = "mck1", .id = 41, },
    409	{ .n = "flex4_clk",	.p = "mck1", .id = 42, },
    410	{ .n = "flex5_clk",	.p = "mck1", .id = 43, },
    411	{ .n = "flex6_clk",	.p = "mck1", .id = 44, },
    412	{ .n = "flex7_clk",	.p = "mck1", .id = 45, },
    413	{ .n = "flex8_clk",	.p = "mck1", .id = 46, },
    414	{ .n = "flex9_clk",	.p = "mck1", .id = 47, },
    415	{ .n = "flex10_clk",	.p = "mck1", .id = 48, },
    416	{ .n = "flex11_clk",	.p = "mck1", .id = 49, },
    417	{ .n = "gmac0_clk",	.p = "mck1", .id = 51, },
    418	{ .n = "gmac1_clk",	.p = "mck1", .id = 52, },
    419	{ .n = "icm_clk",	.p = "mck1", .id = 55, },
    420	{ .n = "isc_clk",	.p = "mck3", .id = 56, .r = { .max = 266000000, }, .chgp = 1, },
    421	{ .n = "i2smcc0_clk",	.p = "mck1", .id = 57, .r = { .max = 200000000, }, },
    422	{ .n = "i2smcc1_clk",	.p = "mck1", .id = 58, .r = { .max = 200000000, }, },
    423	{ .n = "matrix_clk",	.p = "mck1", .id = 60, },
    424	{ .n = "mcan0_clk",	.p = "mck1", .id = 61, .r = { .max = 200000000, }, },
    425	{ .n = "mcan1_clk",	.p = "mck1", .id = 62, .r = { .max = 200000000, }, },
    426	{ .n = "mcan2_clk",	.p = "mck1", .id = 63, .r = { .max = 200000000, }, },
    427	{ .n = "mcan3_clk",	.p = "mck1", .id = 64, .r = { .max = 200000000, }, },
    428	{ .n = "mcan4_clk",	.p = "mck1", .id = 65, .r = { .max = 200000000, }, },
    429	{ .n = "mcan5_clk",	.p = "mck1", .id = 66, .r = { .max = 200000000, }, },
    430	{ .n = "pdmc0_clk",	.p = "mck1", .id = 68, .r = { .max = 200000000, }, },
    431	{ .n = "pdmc1_clk",	.p = "mck1", .id = 69, .r = { .max = 200000000, }, },
    432	{ .n = "pit64b0_clk",	.p = "mck1", .id = 70, },
    433	{ .n = "pit64b1_clk",	.p = "mck1", .id = 71, },
    434	{ .n = "pit64b2_clk",	.p = "mck1", .id = 72, },
    435	{ .n = "pit64b3_clk",	.p = "mck1", .id = 73, },
    436	{ .n = "pit64b4_clk",	.p = "mck1", .id = 74, },
    437	{ .n = "pit64b5_clk",	.p = "mck1", .id = 75, },
    438	{ .n = "pwm_clk",	.p = "mck1", .id = 77, },
    439	{ .n = "qspi0_clk",	.p = "mck1", .id = 78, },
    440	{ .n = "qspi1_clk",	.p = "mck1", .id = 79, },
    441	{ .n = "sdmmc0_clk",	.p = "mck1", .id = 80, },
    442	{ .n = "sdmmc1_clk",	.p = "mck1", .id = 81, },
    443	{ .n = "sdmmc2_clk",	.p = "mck1", .id = 82, },
    444	{ .n = "sha_clk",	.p = "mck1", .id = 83, },
    445	{ .n = "spdifrx_clk",	.p = "mck1", .id = 84, .r = { .max = 200000000, }, },
    446	{ .n = "spdiftx_clk",	.p = "mck1", .id = 85, .r = { .max = 200000000, }, },
    447	{ .n = "ssc0_clk",	.p = "mck1", .id = 86, .r = { .max = 200000000, }, },
    448	{ .n = "ssc1_clk",	.p = "mck1", .id = 87, .r = { .max = 200000000, }, },
    449	{ .n = "tcb0_ch0_clk",	.p = "mck1", .id = 88, .r = { .max = 200000000, }, },
    450	{ .n = "tcb0_ch1_clk",	.p = "mck1", .id = 89, .r = { .max = 200000000, }, },
    451	{ .n = "tcb0_ch2_clk",	.p = "mck1", .id = 90, .r = { .max = 200000000, }, },
    452	{ .n = "tcb1_ch0_clk",	.p = "mck1", .id = 91, .r = { .max = 200000000, }, },
    453	{ .n = "tcb1_ch1_clk",	.p = "mck1", .id = 92, .r = { .max = 200000000, }, },
    454	{ .n = "tcb1_ch2_clk",	.p = "mck1", .id = 93, .r = { .max = 200000000, }, },
    455	{ .n = "tcpca_clk",	.p = "mck1", .id = 94, },
    456	{ .n = "tcpcb_clk",	.p = "mck1", .id = 95, },
    457	{ .n = "tdes_clk",	.p = "mck1", .id = 96, },
    458	{ .n = "trng_clk",	.p = "mck1", .id = 97, },
    459	{ .n = "udphsa_clk",	.p = "mck1", .id = 104, },
    460	{ .n = "udphsb_clk",	.p = "mck1", .id = 105, },
    461	{ .n = "uhphs_clk",	.p = "mck1", .id = 106, },
    462};
    463
    464/*
    465 * Generic clock description
    466 * @n:			clock name
    467 * @pp:			PLL parents
    468 * @pp_mux_table:	PLL parents mux table
    469 * @r:			clock output range
    470 * @pp_chg_id:		id in parent array of changeable PLL parent
    471 * @pp_count:		PLL parents count
    472 * @id:			clock id
    473 */
    474static const struct {
    475	const char *n;
    476	const char *pp[8];
    477	const char pp_mux_table[8];
    478	struct clk_range r;
    479	int pp_chg_id;
    480	u8 pp_count;
    481	u8 id;
    482} sama7g5_gck[] = {
    483	{ .n  = "adc_gclk",
    484	  .id = 26,
    485	  .r = { .max = 100000000, },
    486	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
    487	  .pp_mux_table = { 5, 7, 9, },
    488	  .pp_count = 3,
    489	  .pp_chg_id = INT_MIN, },
    490
    491	{ .n  = "asrc_gclk",
    492	  .id = 30,
    493	  .r = { .max = 200000000 },
    494	  .pp = { "audiopll_divpmcck", },
    495	  .pp_mux_table = { 9, },
    496	  .pp_count = 1,
    497	  .pp_chg_id = 3, },
    498
    499	{ .n  = "csi_gclk",
    500	  .id = 33,
    501	  .r = { .max = 27000000  },
    502	  .pp = { "ddrpll_divpmcck", "imgpll_divpmcck", },
    503	  .pp_mux_table = { 6, 7, },
    504	  .pp_count = 2,
    505	  .pp_chg_id = INT_MIN, },
    506
    507	{ .n  = "flex0_gclk",
    508	  .id = 38,
    509	  .r = { .max = 200000000 },
    510	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    511	  .pp_mux_table = { 5, 8, },
    512	  .pp_count = 2,
    513	  .pp_chg_id = INT_MIN, },
    514
    515	{ .n  = "flex1_gclk",
    516	  .id = 39,
    517	  .r = { .max = 200000000 },
    518	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    519	  .pp_mux_table = { 5, 8, },
    520	  .pp_count = 2,
    521	  .pp_chg_id = INT_MIN, },
    522
    523	{ .n  = "flex2_gclk",
    524	  .id = 40,
    525	  .r = { .max = 200000000 },
    526	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    527	  .pp_mux_table = { 5, 8, },
    528	  .pp_count = 2,
    529	  .pp_chg_id = INT_MIN, },
    530
    531	{ .n  = "flex3_gclk",
    532	  .id = 41,
    533	  .r = { .max = 200000000 },
    534	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    535	  .pp_mux_table = { 5, 8, },
    536	  .pp_count = 2,
    537	  .pp_chg_id = INT_MIN, },
    538
    539	{ .n  = "flex4_gclk",
    540	  .id = 42,
    541	  .r = { .max = 200000000 },
    542	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    543	  .pp_mux_table = { 5, 8, },
    544	  .pp_count = 2,
    545	  .pp_chg_id = INT_MIN, },
    546
    547	{ .n  = "flex5_gclk",
    548	  .id = 43,
    549	  .r = { .max = 200000000 },
    550	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    551	  .pp_mux_table = { 5, 8, },
    552	  .pp_count = 2,
    553	  .pp_chg_id = INT_MIN, },
    554
    555	{ .n  = "flex6_gclk",
    556	  .id = 44,
    557	  .r = { .max = 200000000 },
    558	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    559	  .pp_mux_table = { 5, 8, },
    560	  .pp_count = 2,
    561	  .pp_chg_id = INT_MIN, },
    562
    563	{ .n  = "flex7_gclk",
    564	  .id = 45,
    565	  .r = { .max = 200000000 },
    566	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    567	  .pp_mux_table = { 5, 8, },
    568	  .pp_count = 2,
    569	  .pp_chg_id = INT_MIN, },
    570
    571	{ .n  = "flex8_gclk",
    572	  .id = 46,
    573	  .r = { .max = 200000000 },
    574	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    575	  .pp_mux_table = { 5, 8, },
    576	  .pp_count = 2,
    577	  .pp_chg_id = INT_MIN, },
    578
    579	{ .n  = "flex9_gclk",
    580	  .id = 47,
    581	  .r = { .max = 200000000 },
    582	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    583	  .pp_mux_table = { 5, 8, },
    584	  .pp_count = 2,
    585	  .pp_chg_id = INT_MIN, },
    586
    587	{ .n  = "flex10_gclk",
    588	  .id = 48,
    589	  .r = { .max = 200000000 },
    590	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    591	  .pp_mux_table = { 5, 8, },
    592	  .pp_count = 2,
    593	  .pp_chg_id = INT_MIN, },
    594
    595	{ .n  = "flex11_gclk",
    596	  .id = 49,
    597	  .r = { .max = 200000000 },
    598	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    599	  .pp_mux_table = { 5, 8, },
    600	  .pp_count = 2,
    601	  .pp_chg_id = INT_MIN, },
    602
    603	{ .n  = "gmac0_gclk",
    604	  .id = 51,
    605	  .r = { .max = 125000000 },
    606	  .pp = { "ethpll_divpmcck", },
    607	  .pp_mux_table = { 10, },
    608	  .pp_count = 1,
    609	  .pp_chg_id = 3, },
    610
    611	{ .n  = "gmac1_gclk",
    612	  .id = 52,
    613	  .r = { .max = 50000000  },
    614	  .pp = { "ethpll_divpmcck", },
    615	  .pp_mux_table = { 10, },
    616	  .pp_count = 1,
    617	  .pp_chg_id = INT_MIN, },
    618
    619	{ .n  = "gmac0_tsu_gclk",
    620	  .id = 53,
    621	  .r = { .max = 300000000 },
    622	  .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
    623	  .pp_mux_table = { 9, 10, },
    624	  .pp_count = 2,
    625	  .pp_chg_id = INT_MIN, },
    626
    627	{ .n  = "gmac1_tsu_gclk",
    628	  .id = 54,
    629	  .r = { .max = 300000000 },
    630	  .pp = { "audiopll_divpmcck", "ethpll_divpmcck", },
    631	  .pp_mux_table = { 9, 10, },
    632	  .pp_count = 2,
    633	  .pp_chg_id = INT_MIN, },
    634
    635	{ .n  = "i2smcc0_gclk",
    636	  .id = 57,
    637	  .r = { .max = 100000000 },
    638	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    639	  .pp_mux_table = { 5, 9, },
    640	  .pp_count = 2,
    641	  .pp_chg_id = 4, },
    642
    643	{ .n  = "i2smcc1_gclk",
    644	  .id = 58,
    645	  .r = { .max = 100000000 },
    646	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    647	  .pp_mux_table = { 5, 9, },
    648	  .pp_count = 2,
    649	  .pp_chg_id = 4, },
    650
    651	{ .n  = "mcan0_gclk",
    652	  .id = 61,
    653	  .r = { .max = 200000000 },
    654	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    655	  .pp_mux_table = { 5, 8, },
    656	  .pp_count = 2,
    657	  .pp_chg_id = INT_MIN, },
    658
    659	{ .n  = "mcan1_gclk",
    660	  .id = 62,
    661	  .r = { .max = 200000000 },
    662	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    663	  .pp_mux_table = { 5, 8, },
    664	  .pp_count = 2,
    665	  .pp_chg_id = INT_MIN, },
    666
    667	{ .n  = "mcan2_gclk",
    668	  .id = 63,
    669	  .r = { .max = 200000000 },
    670	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    671	  .pp_mux_table = { 5, 8, },
    672	  .pp_count = 2,
    673	  .pp_chg_id = INT_MIN, },
    674
    675	{ .n  = "mcan3_gclk",
    676	  .id = 64,
    677	  .r = { .max = 200000000 },
    678	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    679	  .pp_mux_table = { 5, 8, },
    680	  .pp_count = 2,
    681	  .pp_chg_id = INT_MIN, },
    682
    683	{ .n  = "mcan4_gclk",
    684	  .id = 65,
    685	  .r = { .max = 200000000 },
    686	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    687	  .pp_mux_table = { 5, 8, },
    688	  .pp_count = 2,
    689	  .pp_chg_id = INT_MIN, },
    690
    691	{ .n  = "mcan5_gclk",
    692	  .id = 66,
    693	  .r = { .max = 200000000 },
    694	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    695	  .pp_mux_table = { 5, 8, },
    696	  .pp_count = 2,
    697	  .pp_chg_id = INT_MIN, },
    698
    699	{ .n  = "pdmc0_gclk",
    700	  .id = 68,
    701	  .r = { .max = 50000000  },
    702	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    703	  .pp_mux_table = { 5, 9, },
    704	  .pp_count = 2,
    705	  .pp_chg_id = INT_MIN, },
    706
    707	{ .n  = "pdmc1_gclk",
    708	  .id = 69,
    709	  .r = { .max = 50000000, },
    710	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    711	  .pp_mux_table = { 5, 9, },
    712	  .pp_count = 2,
    713	  .pp_chg_id = INT_MIN, },
    714
    715	{ .n  = "pit64b0_gclk",
    716	  .id = 70,
    717	  .r = { .max = 200000000 },
    718	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    719		  "audiopll_divpmcck", "ethpll_divpmcck", },
    720	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    721	  .pp_count = 5,
    722	  .pp_chg_id = INT_MIN, },
    723
    724	{ .n  = "pit64b1_gclk",
    725	  .id = 71,
    726	  .r = { .max = 200000000 },
    727	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    728		  "audiopll_divpmcck", "ethpll_divpmcck", },
    729	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    730	  .pp_count = 5,
    731	  .pp_chg_id = INT_MIN, },
    732
    733	{ .n  = "pit64b2_gclk",
    734	  .id = 72,
    735	  .r = { .max = 200000000 },
    736	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    737		  "audiopll_divpmcck", "ethpll_divpmcck", },
    738	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    739	  .pp_count = 5,
    740	  .pp_chg_id = INT_MIN, },
    741
    742	{ .n  = "pit64b3_gclk",
    743	  .id = 73,
    744	  .r = { .max = 200000000 },
    745	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    746		  "audiopll_divpmcck", "ethpll_divpmcck", },
    747	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    748	  .pp_count = 5,
    749	  .pp_chg_id = INT_MIN, },
    750
    751	{ .n  = "pit64b4_gclk",
    752	  .id = 74,
    753	  .r = { .max = 200000000 },
    754	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    755		  "audiopll_divpmcck", "ethpll_divpmcck", },
    756	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    757	  .pp_count = 5,
    758	  .pp_chg_id = INT_MIN, },
    759
    760	{ .n  = "pit64b5_gclk",
    761	  .id = 75,
    762	  .r = { .max = 200000000 },
    763	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    764		  "audiopll_divpmcck", "ethpll_divpmcck", },
    765	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    766	  .pp_count = 5,
    767	  .pp_chg_id = INT_MIN, },
    768
    769	{ .n  = "qspi0_gclk",
    770	  .id = 78,
    771	  .r = { .max = 200000000 },
    772	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    773	  .pp_mux_table = { 5, 8, },
    774	  .pp_count = 2,
    775	  .pp_chg_id = INT_MIN, },
    776
    777	{ .n  = "qspi1_gclk",
    778	  .id = 79,
    779	  .r = { .max = 200000000 },
    780	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    781	  .pp_mux_table = { 5, 8, },
    782	  .pp_count = 2,
    783	  .pp_chg_id = INT_MIN, },
    784
    785	{ .n  = "sdmmc0_gclk",
    786	  .id = 80,
    787	  .r = { .max = 208000000 },
    788	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    789	  .pp_mux_table = { 5, 8, },
    790	  .pp_count = 2,
    791	  .pp_chg_id = 4, },
    792
    793	{ .n  = "sdmmc1_gclk",
    794	  .id = 81,
    795	  .r = { .max = 208000000 },
    796	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    797	  .pp_mux_table = { 5, 8, },
    798	  .pp_count = 2,
    799	  .pp_chg_id = 4, },
    800
    801	{ .n  = "sdmmc2_gclk",
    802	  .id = 82,
    803	  .r = { .max = 208000000 },
    804	  .pp = { "syspll_divpmcck", "baudpll_divpmcck", },
    805	  .pp_mux_table = { 5, 8, },
    806	  .pp_count = 2,
    807	  .pp_chg_id = 4, },
    808
    809	{ .n  = "spdifrx_gclk",
    810	  .id = 84,
    811	  .r = { .max = 150000000 },
    812	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    813	  .pp_mux_table = { 5, 9, },
    814	  .pp_count = 2,
    815	  .pp_chg_id = 4, },
    816
    817	{ .n = "spdiftx_gclk",
    818	  .id = 85,
    819	  .r = { .max = 25000000  },
    820	  .pp = { "syspll_divpmcck", "audiopll_divpmcck", },
    821	  .pp_mux_table = { 5, 9, },
    822	  .pp_count = 2,
    823	  .pp_chg_id = 4, },
    824
    825	{ .n  = "tcb0_ch0_gclk",
    826	  .id = 88,
    827	  .r = { .max = 200000000 },
    828	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    829		  "audiopll_divpmcck", "ethpll_divpmcck", },
    830	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    831	  .pp_count = 5,
    832	  .pp_chg_id = INT_MIN, },
    833
    834	{ .n  = "tcb1_ch0_gclk",
    835	  .id = 91,
    836	  .r = { .max = 200000000 },
    837	  .pp = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
    838		  "audiopll_divpmcck", "ethpll_divpmcck", },
    839	  .pp_mux_table = { 5, 7, 8, 9, 10, },
    840	  .pp_count = 5,
    841	  .pp_chg_id = INT_MIN, },
    842
    843	{ .n  = "tcpca_gclk",
    844	  .id = 94,
    845	  .r = { .max = 32768, },
    846	  .pp_chg_id = INT_MIN, },
    847
    848	{ .n  = "tcpcb_gclk",
    849	  .id = 95,
    850	  .r = { .max = 32768, },
    851	  .pp_chg_id = INT_MIN, },
    852};
    853
    854/* MCK0 characteristics. */
    855static const struct clk_master_characteristics mck0_characteristics = {
    856	.output = { .min = 32768, .max = 200000000 },
    857	.divisors = { 1, 2, 4, 3, 5 },
    858	.have_div3_pres = 1,
    859};
    860
    861/* MCK0 layout. */
    862static const struct clk_master_layout mck0_layout = {
    863	.mask = 0x773,
    864	.pres_shift = 4,
    865	.offset = 0x28,
    866};
    867
    868/* Programmable clock layout. */
    869static const struct clk_programmable_layout programmable_layout = {
    870	.pres_mask = 0xff,
    871	.pres_shift = 8,
    872	.css_mask = 0x1f,
    873	.have_slck_mck = 0,
    874	.is_pres_direct = 1,
    875};
    876
    877/* Peripheral clock layout. */
    878static const struct clk_pcr_layout sama7g5_pcr_layout = {
    879	.offset = 0x88,
    880	.cmd = BIT(31),
    881	.gckcss_mask = GENMASK(12, 8),
    882	.pid_mask = GENMASK(6, 0),
    883};
    884
    885static void __init sama7g5_pmc_setup(struct device_node *np)
    886{
    887	const char *td_slck_name, *md_slck_name, *mainxtal_name;
    888	struct pmc_data *sama7g5_pmc;
    889	const char *parent_names[10];
    890	void **alloc_mem = NULL;
    891	int alloc_mem_size = 0;
    892	struct regmap *regmap;
    893	struct clk_hw *hw;
    894	bool bypass;
    895	int i, j;
    896
    897	i = of_property_match_string(np, "clock-names", "td_slck");
    898	if (i < 0)
    899		return;
    900
    901	td_slck_name = of_clk_get_parent_name(np, i);
    902
    903	i = of_property_match_string(np, "clock-names", "md_slck");
    904	if (i < 0)
    905		return;
    906
    907	md_slck_name = of_clk_get_parent_name(np, i);
    908
    909	i = of_property_match_string(np, "clock-names", "main_xtal");
    910	if (i < 0)
    911		return;
    912
    913	mainxtal_name = of_clk_get_parent_name(np, i);
    914
    915	regmap = device_node_to_regmap(np);
    916	if (IS_ERR(regmap))
    917		return;
    918
    919	sama7g5_pmc = pmc_data_allocate(PMC_MCK1 + 1,
    920					nck(sama7g5_systemck),
    921					nck(sama7g5_periphck),
    922					nck(sama7g5_gck), 8);
    923	if (!sama7g5_pmc)
    924		return;
    925
    926	alloc_mem = kmalloc(sizeof(void *) *
    927			    (ARRAY_SIZE(sama7g5_mckx) + ARRAY_SIZE(sama7g5_gck)),
    928			    GFP_KERNEL);
    929	if (!alloc_mem)
    930		goto err_free;
    931
    932	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
    933					   50000000);
    934	if (IS_ERR(hw))
    935		goto err_free;
    936
    937	bypass = of_property_read_bool(np, "atmel,osc-bypass");
    938
    939	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
    940					bypass);
    941	if (IS_ERR(hw))
    942		goto err_free;
    943
    944	parent_names[0] = "main_rc_osc";
    945	parent_names[1] = "main_osc";
    946	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
    947	if (IS_ERR(hw))
    948		goto err_free;
    949
    950	sama7g5_pmc->chws[PMC_MAIN] = hw;
    951
    952	for (i = 0; i < PLL_ID_MAX; i++) {
    953		for (j = 0; j < 3; j++) {
    954			struct clk_hw *parent_hw;
    955
    956			if (!sama7g5_plls[i][j].n)
    957				continue;
    958
    959			switch (sama7g5_plls[i][j].t) {
    960			case PLL_TYPE_FRAC:
    961				if (!strcmp(sama7g5_plls[i][j].p, "mainck"))
    962					parent_hw = sama7g5_pmc->chws[PMC_MAIN];
    963				else
    964					parent_hw = __clk_get_hw(of_clk_get_by_name(np,
    965						sama7g5_plls[i][j].p));
    966
    967				hw = sam9x60_clk_register_frac_pll(regmap,
    968					&pmc_pll_lock, sama7g5_plls[i][j].n,
    969					sama7g5_plls[i][j].p, parent_hw, i,
    970					sama7g5_plls[i][j].c,
    971					sama7g5_plls[i][j].l,
    972					sama7g5_plls[i][j].f);
    973				break;
    974
    975			case PLL_TYPE_DIV:
    976				hw = sam9x60_clk_register_div_pll(regmap,
    977					&pmc_pll_lock, sama7g5_plls[i][j].n,
    978					sama7g5_plls[i][j].p, i,
    979					sama7g5_plls[i][j].c,
    980					sama7g5_plls[i][j].l,
    981					sama7g5_plls[i][j].f,
    982					sama7g5_plls[i][j].safe_div);
    983				break;
    984
    985			default:
    986				continue;
    987			}
    988
    989			if (IS_ERR(hw))
    990				goto err_free;
    991
    992			if (sama7g5_plls[i][j].eid)
    993				sama7g5_pmc->chws[sama7g5_plls[i][j].eid] = hw;
    994		}
    995	}
    996
    997	parent_names[0] = "cpupll_divpmcck";
    998	hw = at91_clk_register_master_div(regmap, "mck0", "cpupll_divpmcck",
    999					  &mck0_layout, &mck0_characteristics,
   1000					  &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5);
   1001	if (IS_ERR(hw))
   1002		goto err_free;
   1003
   1004	sama7g5_pmc->chws[PMC_MCK] = hw;
   1005
   1006	parent_names[0] = md_slck_name;
   1007	parent_names[1] = td_slck_name;
   1008	parent_names[2] = "mainck";
   1009	for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
   1010		u8 num_parents = 3 + sama7g5_mckx[i].ep_count;
   1011		u32 *mux_table;
   1012
   1013		mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
   1014					  GFP_KERNEL);
   1015		if (!mux_table)
   1016			goto err_free;
   1017
   1018		SAMA7G5_INIT_TABLE(mux_table, 3);
   1019		SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
   1020				   sama7g5_mckx[i].ep_count);
   1021		SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_mckx[i].ep,
   1022				   sama7g5_mckx[i].ep_count);
   1023
   1024		hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
   1025				   num_parents, parent_names, mux_table,
   1026				   &pmc_mckX_lock, sama7g5_mckx[i].id,
   1027				   sama7g5_mckx[i].c,
   1028				   sama7g5_mckx[i].ep_chg_id);
   1029		if (IS_ERR(hw))
   1030			goto err_free;
   1031
   1032		alloc_mem[alloc_mem_size++] = mux_table;
   1033
   1034		if (sama7g5_mckx[i].eid)
   1035			sama7g5_pmc->chws[sama7g5_mckx[i].eid] = hw;
   1036	}
   1037
   1038	hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal");
   1039	if (IS_ERR(hw))
   1040		goto err_free;
   1041
   1042	sama7g5_pmc->chws[PMC_UTMI] = hw;
   1043
   1044	parent_names[0] = md_slck_name;
   1045	parent_names[1] = td_slck_name;
   1046	parent_names[2] = "mainck";
   1047	parent_names[3] = "syspll_divpmcck";
   1048	parent_names[4] = "ddrpll_divpmcck";
   1049	parent_names[5] = "imgpll_divpmcck";
   1050	parent_names[6] = "baudpll_divpmcck";
   1051	parent_names[7] = "audiopll_divpmcck";
   1052	parent_names[8] = "ethpll_divpmcck";
   1053	for (i = 0; i < 8; i++) {
   1054		char name[6];
   1055
   1056		snprintf(name, sizeof(name), "prog%d", i);
   1057
   1058		hw = at91_clk_register_programmable(regmap, name, parent_names,
   1059						    9, i,
   1060						    &programmable_layout,
   1061						    sama7g5_prog_mux_table);
   1062		if (IS_ERR(hw))
   1063			goto err_free;
   1064
   1065		sama7g5_pmc->pchws[i] = hw;
   1066	}
   1067
   1068	for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
   1069		hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
   1070					      sama7g5_systemck[i].p,
   1071					      sama7g5_systemck[i].id);
   1072		if (IS_ERR(hw))
   1073			goto err_free;
   1074
   1075		sama7g5_pmc->shws[sama7g5_systemck[i].id] = hw;
   1076	}
   1077
   1078	for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
   1079		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
   1080						&sama7g5_pcr_layout,
   1081						sama7g5_periphck[i].n,
   1082						sama7g5_periphck[i].p,
   1083						sama7g5_periphck[i].id,
   1084						&sama7g5_periphck[i].r,
   1085						sama7g5_periphck[i].chgp ? 0 :
   1086						INT_MIN);
   1087		if (IS_ERR(hw))
   1088			goto err_free;
   1089
   1090		sama7g5_pmc->phws[sama7g5_periphck[i].id] = hw;
   1091	}
   1092
   1093	parent_names[0] = md_slck_name;
   1094	parent_names[1] = td_slck_name;
   1095	parent_names[2] = "mainck";
   1096	for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
   1097		u8 num_parents = 3 + sama7g5_gck[i].pp_count;
   1098		u32 *mux_table;
   1099
   1100		mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
   1101					  GFP_KERNEL);
   1102		if (!mux_table)
   1103			goto err_free;
   1104
   1105		SAMA7G5_INIT_TABLE(mux_table, 3);
   1106		SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
   1107				   sama7g5_gck[i].pp_count);
   1108		SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_gck[i].pp,
   1109				   sama7g5_gck[i].pp_count);
   1110
   1111		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
   1112						 &sama7g5_pcr_layout,
   1113						 sama7g5_gck[i].n,
   1114						 parent_names, mux_table,
   1115						 num_parents,
   1116						 sama7g5_gck[i].id,
   1117						 &sama7g5_gck[i].r,
   1118						 sama7g5_gck[i].pp_chg_id);
   1119		if (IS_ERR(hw))
   1120			goto err_free;
   1121
   1122		sama7g5_pmc->ghws[sama7g5_gck[i].id] = hw;
   1123		alloc_mem[alloc_mem_size++] = mux_table;
   1124	}
   1125
   1126	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7g5_pmc);
   1127
   1128	return;
   1129
   1130err_free:
   1131	if (alloc_mem) {
   1132		for (i = 0; i < alloc_mem_size; i++)
   1133			kfree(alloc_mem[i]);
   1134		kfree(alloc_mem);
   1135	}
   1136
   1137	kfree(sama7g5_pmc);
   1138}
   1139
   1140/* Some clks are used for a clocksource */
   1141CLK_OF_DECLARE(sama7g5_pmc, "microchip,sama7g5-pmc", sama7g5_pmc_setup);