1738f66d3SMichael Turquette /* 21f501d63SPaul Gortmaker * AmLogic S905 / GXBB Clock Controller Driver 31f501d63SPaul Gortmaker * 4738f66d3SMichael Turquette * Copyright (c) 2016 AmLogic, Inc. 5738f66d3SMichael Turquette * Michael Turquette <mturquette@baylibre.com> 6738f66d3SMichael Turquette * 7738f66d3SMichael Turquette * This program is free software; you can redistribute it and/or modify it 8738f66d3SMichael Turquette * under the terms and conditions of the GNU General Public License, 9738f66d3SMichael Turquette * version 2, as published by the Free Software Foundation. 10738f66d3SMichael Turquette * 11738f66d3SMichael Turquette * This program is distributed in the hope it will be useful, but WITHOUT 12738f66d3SMichael Turquette * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13738f66d3SMichael Turquette * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14738f66d3SMichael Turquette * more details. 15738f66d3SMichael Turquette * 16738f66d3SMichael Turquette * You should have received a copy of the GNU General Public License along with 17738f66d3SMichael Turquette * this program. If not, see <http://www.gnu.org/licenses/>. 18738f66d3SMichael Turquette */ 19738f66d3SMichael Turquette 20738f66d3SMichael Turquette #include <linux/clk.h> 21738f66d3SMichael Turquette #include <linux/clk-provider.h> 22738f66d3SMichael Turquette #include <linux/of_address.h> 23738f66d3SMichael Turquette #include <linux/platform_device.h> 241f501d63SPaul Gortmaker #include <linux/init.h> 25738f66d3SMichael Turquette 26738f66d3SMichael Turquette #include "clkc.h" 27738f66d3SMichael Turquette #include "gxbb.h" 28738f66d3SMichael Turquette 29738f66d3SMichael Turquette static DEFINE_SPINLOCK(clk_lock); 30738f66d3SMichael Turquette 31738f66d3SMichael Turquette static const struct pll_rate_table sys_pll_rate_table[] = { 32738f66d3SMichael Turquette PLL_RATE(24000000, 56, 1, 2), 33738f66d3SMichael Turquette PLL_RATE(48000000, 64, 1, 2), 34738f66d3SMichael Turquette PLL_RATE(72000000, 72, 1, 2), 35738f66d3SMichael Turquette PLL_RATE(96000000, 64, 1, 2), 36738f66d3SMichael Turquette PLL_RATE(120000000, 80, 1, 2), 37738f66d3SMichael Turquette PLL_RATE(144000000, 96, 1, 2), 38738f66d3SMichael Turquette PLL_RATE(168000000, 56, 1, 1), 39738f66d3SMichael Turquette PLL_RATE(192000000, 64, 1, 1), 40738f66d3SMichael Turquette PLL_RATE(216000000, 72, 1, 1), 41738f66d3SMichael Turquette PLL_RATE(240000000, 80, 1, 1), 42738f66d3SMichael Turquette PLL_RATE(264000000, 88, 1, 1), 43738f66d3SMichael Turquette PLL_RATE(288000000, 96, 1, 1), 44738f66d3SMichael Turquette PLL_RATE(312000000, 52, 1, 2), 45738f66d3SMichael Turquette PLL_RATE(336000000, 56, 1, 2), 46738f66d3SMichael Turquette PLL_RATE(360000000, 60, 1, 2), 47738f66d3SMichael Turquette PLL_RATE(384000000, 64, 1, 2), 48738f66d3SMichael Turquette PLL_RATE(408000000, 68, 1, 2), 49738f66d3SMichael Turquette PLL_RATE(432000000, 72, 1, 2), 50738f66d3SMichael Turquette PLL_RATE(456000000, 76, 1, 2), 51738f66d3SMichael Turquette PLL_RATE(480000000, 80, 1, 2), 52738f66d3SMichael Turquette PLL_RATE(504000000, 84, 1, 2), 53738f66d3SMichael Turquette PLL_RATE(528000000, 88, 1, 2), 54738f66d3SMichael Turquette PLL_RATE(552000000, 92, 1, 2), 55738f66d3SMichael Turquette PLL_RATE(576000000, 96, 1, 2), 56738f66d3SMichael Turquette PLL_RATE(600000000, 50, 1, 1), 57738f66d3SMichael Turquette PLL_RATE(624000000, 52, 1, 1), 58738f66d3SMichael Turquette PLL_RATE(648000000, 54, 1, 1), 59738f66d3SMichael Turquette PLL_RATE(672000000, 56, 1, 1), 60738f66d3SMichael Turquette PLL_RATE(696000000, 58, 1, 1), 61738f66d3SMichael Turquette PLL_RATE(720000000, 60, 1, 1), 62738f66d3SMichael Turquette PLL_RATE(744000000, 62, 1, 1), 63738f66d3SMichael Turquette PLL_RATE(768000000, 64, 1, 1), 64738f66d3SMichael Turquette PLL_RATE(792000000, 66, 1, 1), 65738f66d3SMichael Turquette PLL_RATE(816000000, 68, 1, 1), 66738f66d3SMichael Turquette PLL_RATE(840000000, 70, 1, 1), 67738f66d3SMichael Turquette PLL_RATE(864000000, 72, 1, 1), 68738f66d3SMichael Turquette PLL_RATE(888000000, 74, 1, 1), 69738f66d3SMichael Turquette PLL_RATE(912000000, 76, 1, 1), 70738f66d3SMichael Turquette PLL_RATE(936000000, 78, 1, 1), 71738f66d3SMichael Turquette PLL_RATE(960000000, 80, 1, 1), 72738f66d3SMichael Turquette PLL_RATE(984000000, 82, 1, 1), 73738f66d3SMichael Turquette PLL_RATE(1008000000, 84, 1, 1), 74738f66d3SMichael Turquette PLL_RATE(1032000000, 86, 1, 1), 75738f66d3SMichael Turquette PLL_RATE(1056000000, 88, 1, 1), 76738f66d3SMichael Turquette PLL_RATE(1080000000, 90, 1, 1), 77738f66d3SMichael Turquette PLL_RATE(1104000000, 92, 1, 1), 78738f66d3SMichael Turquette PLL_RATE(1128000000, 94, 1, 1), 79738f66d3SMichael Turquette PLL_RATE(1152000000, 96, 1, 1), 80738f66d3SMichael Turquette PLL_RATE(1176000000, 98, 1, 1), 81738f66d3SMichael Turquette PLL_RATE(1200000000, 50, 1, 0), 82738f66d3SMichael Turquette PLL_RATE(1224000000, 51, 1, 0), 83738f66d3SMichael Turquette PLL_RATE(1248000000, 52, 1, 0), 84738f66d3SMichael Turquette PLL_RATE(1272000000, 53, 1, 0), 85738f66d3SMichael Turquette PLL_RATE(1296000000, 54, 1, 0), 86738f66d3SMichael Turquette PLL_RATE(1320000000, 55, 1, 0), 87738f66d3SMichael Turquette PLL_RATE(1344000000, 56, 1, 0), 88738f66d3SMichael Turquette PLL_RATE(1368000000, 57, 1, 0), 89738f66d3SMichael Turquette PLL_RATE(1392000000, 58, 1, 0), 90738f66d3SMichael Turquette PLL_RATE(1416000000, 59, 1, 0), 91738f66d3SMichael Turquette PLL_RATE(1440000000, 60, 1, 0), 92738f66d3SMichael Turquette PLL_RATE(1464000000, 61, 1, 0), 93738f66d3SMichael Turquette PLL_RATE(1488000000, 62, 1, 0), 94738f66d3SMichael Turquette PLL_RATE(1512000000, 63, 1, 0), 95738f66d3SMichael Turquette PLL_RATE(1536000000, 64, 1, 0), 96738f66d3SMichael Turquette PLL_RATE(1560000000, 65, 1, 0), 97738f66d3SMichael Turquette PLL_RATE(1584000000, 66, 1, 0), 98738f66d3SMichael Turquette PLL_RATE(1608000000, 67, 1, 0), 99738f66d3SMichael Turquette PLL_RATE(1632000000, 68, 1, 0), 100738f66d3SMichael Turquette PLL_RATE(1656000000, 68, 1, 0), 101738f66d3SMichael Turquette PLL_RATE(1680000000, 68, 1, 0), 102738f66d3SMichael Turquette PLL_RATE(1704000000, 68, 1, 0), 103738f66d3SMichael Turquette PLL_RATE(1728000000, 69, 1, 0), 104738f66d3SMichael Turquette PLL_RATE(1752000000, 69, 1, 0), 105738f66d3SMichael Turquette PLL_RATE(1776000000, 69, 1, 0), 106738f66d3SMichael Turquette PLL_RATE(1800000000, 69, 1, 0), 107738f66d3SMichael Turquette PLL_RATE(1824000000, 70, 1, 0), 108738f66d3SMichael Turquette PLL_RATE(1848000000, 70, 1, 0), 109738f66d3SMichael Turquette PLL_RATE(1872000000, 70, 1, 0), 110738f66d3SMichael Turquette PLL_RATE(1896000000, 70, 1, 0), 111738f66d3SMichael Turquette PLL_RATE(1920000000, 71, 1, 0), 112738f66d3SMichael Turquette PLL_RATE(1944000000, 71, 1, 0), 113738f66d3SMichael Turquette PLL_RATE(1968000000, 71, 1, 0), 114738f66d3SMichael Turquette PLL_RATE(1992000000, 71, 1, 0), 115738f66d3SMichael Turquette PLL_RATE(2016000000, 72, 1, 0), 116738f66d3SMichael Turquette PLL_RATE(2040000000, 72, 1, 0), 117738f66d3SMichael Turquette PLL_RATE(2064000000, 72, 1, 0), 118738f66d3SMichael Turquette PLL_RATE(2088000000, 72, 1, 0), 119738f66d3SMichael Turquette PLL_RATE(2112000000, 73, 1, 0), 120738f66d3SMichael Turquette { /* sentinel */ }, 121738f66d3SMichael Turquette }; 122738f66d3SMichael Turquette 123738f66d3SMichael Turquette static const struct pll_rate_table gp0_pll_rate_table[] = { 124738f66d3SMichael Turquette PLL_RATE(96000000, 32, 1, 3), 125738f66d3SMichael Turquette PLL_RATE(99000000, 33, 1, 3), 126738f66d3SMichael Turquette PLL_RATE(102000000, 34, 1, 3), 127738f66d3SMichael Turquette PLL_RATE(105000000, 35, 1, 3), 128738f66d3SMichael Turquette PLL_RATE(108000000, 36, 1, 3), 129738f66d3SMichael Turquette PLL_RATE(111000000, 37, 1, 3), 130738f66d3SMichael Turquette PLL_RATE(114000000, 38, 1, 3), 131738f66d3SMichael Turquette PLL_RATE(117000000, 39, 1, 3), 132738f66d3SMichael Turquette PLL_RATE(120000000, 40, 1, 3), 133738f66d3SMichael Turquette PLL_RATE(123000000, 41, 1, 3), 134738f66d3SMichael Turquette PLL_RATE(126000000, 42, 1, 3), 135738f66d3SMichael Turquette PLL_RATE(129000000, 43, 1, 3), 136738f66d3SMichael Turquette PLL_RATE(132000000, 44, 1, 3), 137738f66d3SMichael Turquette PLL_RATE(135000000, 45, 1, 3), 138738f66d3SMichael Turquette PLL_RATE(138000000, 46, 1, 3), 139738f66d3SMichael Turquette PLL_RATE(141000000, 47, 1, 3), 140738f66d3SMichael Turquette PLL_RATE(144000000, 48, 1, 3), 141738f66d3SMichael Turquette PLL_RATE(147000000, 49, 1, 3), 142738f66d3SMichael Turquette PLL_RATE(150000000, 50, 1, 3), 143738f66d3SMichael Turquette PLL_RATE(153000000, 51, 1, 3), 144738f66d3SMichael Turquette PLL_RATE(156000000, 52, 1, 3), 145738f66d3SMichael Turquette PLL_RATE(159000000, 53, 1, 3), 146738f66d3SMichael Turquette PLL_RATE(162000000, 54, 1, 3), 147738f66d3SMichael Turquette PLL_RATE(165000000, 55, 1, 3), 148738f66d3SMichael Turquette PLL_RATE(168000000, 56, 1, 3), 149738f66d3SMichael Turquette PLL_RATE(171000000, 57, 1, 3), 150738f66d3SMichael Turquette PLL_RATE(174000000, 58, 1, 3), 151738f66d3SMichael Turquette PLL_RATE(177000000, 59, 1, 3), 152738f66d3SMichael Turquette PLL_RATE(180000000, 60, 1, 3), 153738f66d3SMichael Turquette PLL_RATE(183000000, 61, 1, 3), 154738f66d3SMichael Turquette PLL_RATE(186000000, 62, 1, 3), 155738f66d3SMichael Turquette PLL_RATE(192000000, 32, 1, 2), 156738f66d3SMichael Turquette PLL_RATE(198000000, 33, 1, 2), 157738f66d3SMichael Turquette PLL_RATE(204000000, 34, 1, 2), 158738f66d3SMichael Turquette PLL_RATE(210000000, 35, 1, 2), 159738f66d3SMichael Turquette PLL_RATE(216000000, 36, 1, 2), 160738f66d3SMichael Turquette PLL_RATE(222000000, 37, 1, 2), 161738f66d3SMichael Turquette PLL_RATE(228000000, 38, 1, 2), 162738f66d3SMichael Turquette PLL_RATE(234000000, 39, 1, 2), 163738f66d3SMichael Turquette PLL_RATE(240000000, 40, 1, 2), 164738f66d3SMichael Turquette PLL_RATE(246000000, 41, 1, 2), 165738f66d3SMichael Turquette PLL_RATE(252000000, 42, 1, 2), 166738f66d3SMichael Turquette PLL_RATE(258000000, 43, 1, 2), 167738f66d3SMichael Turquette PLL_RATE(264000000, 44, 1, 2), 168738f66d3SMichael Turquette PLL_RATE(270000000, 45, 1, 2), 169738f66d3SMichael Turquette PLL_RATE(276000000, 46, 1, 2), 170738f66d3SMichael Turquette PLL_RATE(282000000, 47, 1, 2), 171738f66d3SMichael Turquette PLL_RATE(288000000, 48, 1, 2), 172738f66d3SMichael Turquette PLL_RATE(294000000, 49, 1, 2), 173738f66d3SMichael Turquette PLL_RATE(300000000, 50, 1, 2), 174738f66d3SMichael Turquette PLL_RATE(306000000, 51, 1, 2), 175738f66d3SMichael Turquette PLL_RATE(312000000, 52, 1, 2), 176738f66d3SMichael Turquette PLL_RATE(318000000, 53, 1, 2), 177738f66d3SMichael Turquette PLL_RATE(324000000, 54, 1, 2), 178738f66d3SMichael Turquette PLL_RATE(330000000, 55, 1, 2), 179738f66d3SMichael Turquette PLL_RATE(336000000, 56, 1, 2), 180738f66d3SMichael Turquette PLL_RATE(342000000, 57, 1, 2), 181738f66d3SMichael Turquette PLL_RATE(348000000, 58, 1, 2), 182738f66d3SMichael Turquette PLL_RATE(354000000, 59, 1, 2), 183738f66d3SMichael Turquette PLL_RATE(360000000, 60, 1, 2), 184738f66d3SMichael Turquette PLL_RATE(366000000, 61, 1, 2), 185738f66d3SMichael Turquette PLL_RATE(372000000, 62, 1, 2), 186738f66d3SMichael Turquette PLL_RATE(384000000, 32, 1, 1), 187738f66d3SMichael Turquette PLL_RATE(396000000, 33, 1, 1), 188738f66d3SMichael Turquette PLL_RATE(408000000, 34, 1, 1), 189738f66d3SMichael Turquette PLL_RATE(420000000, 35, 1, 1), 190738f66d3SMichael Turquette PLL_RATE(432000000, 36, 1, 1), 191738f66d3SMichael Turquette PLL_RATE(444000000, 37, 1, 1), 192738f66d3SMichael Turquette PLL_RATE(456000000, 38, 1, 1), 193738f66d3SMichael Turquette PLL_RATE(468000000, 39, 1, 1), 194738f66d3SMichael Turquette PLL_RATE(480000000, 40, 1, 1), 195738f66d3SMichael Turquette PLL_RATE(492000000, 41, 1, 1), 196738f66d3SMichael Turquette PLL_RATE(504000000, 42, 1, 1), 197738f66d3SMichael Turquette PLL_RATE(516000000, 43, 1, 1), 198738f66d3SMichael Turquette PLL_RATE(528000000, 44, 1, 1), 199738f66d3SMichael Turquette PLL_RATE(540000000, 45, 1, 1), 200738f66d3SMichael Turquette PLL_RATE(552000000, 46, 1, 1), 201738f66d3SMichael Turquette PLL_RATE(564000000, 47, 1, 1), 202738f66d3SMichael Turquette PLL_RATE(576000000, 48, 1, 1), 203738f66d3SMichael Turquette PLL_RATE(588000000, 49, 1, 1), 204738f66d3SMichael Turquette PLL_RATE(600000000, 50, 1, 1), 205738f66d3SMichael Turquette PLL_RATE(612000000, 51, 1, 1), 206738f66d3SMichael Turquette PLL_RATE(624000000, 52, 1, 1), 207738f66d3SMichael Turquette PLL_RATE(636000000, 53, 1, 1), 208738f66d3SMichael Turquette PLL_RATE(648000000, 54, 1, 1), 209738f66d3SMichael Turquette PLL_RATE(660000000, 55, 1, 1), 210738f66d3SMichael Turquette PLL_RATE(672000000, 56, 1, 1), 211738f66d3SMichael Turquette PLL_RATE(684000000, 57, 1, 1), 212738f66d3SMichael Turquette PLL_RATE(696000000, 58, 1, 1), 213738f66d3SMichael Turquette PLL_RATE(708000000, 59, 1, 1), 214738f66d3SMichael Turquette PLL_RATE(720000000, 60, 1, 1), 215738f66d3SMichael Turquette PLL_RATE(732000000, 61, 1, 1), 216738f66d3SMichael Turquette PLL_RATE(744000000, 62, 1, 1), 217738f66d3SMichael Turquette PLL_RATE(768000000, 32, 1, 0), 218738f66d3SMichael Turquette PLL_RATE(792000000, 33, 1, 0), 219738f66d3SMichael Turquette PLL_RATE(816000000, 34, 1, 0), 220738f66d3SMichael Turquette PLL_RATE(840000000, 35, 1, 0), 221738f66d3SMichael Turquette PLL_RATE(864000000, 36, 1, 0), 222738f66d3SMichael Turquette PLL_RATE(888000000, 37, 1, 0), 223738f66d3SMichael Turquette PLL_RATE(912000000, 38, 1, 0), 224738f66d3SMichael Turquette PLL_RATE(936000000, 39, 1, 0), 225738f66d3SMichael Turquette PLL_RATE(960000000, 40, 1, 0), 226738f66d3SMichael Turquette PLL_RATE(984000000, 41, 1, 0), 227738f66d3SMichael Turquette PLL_RATE(1008000000, 42, 1, 0), 228738f66d3SMichael Turquette PLL_RATE(1032000000, 43, 1, 0), 229738f66d3SMichael Turquette PLL_RATE(1056000000, 44, 1, 0), 230738f66d3SMichael Turquette PLL_RATE(1080000000, 45, 1, 0), 231738f66d3SMichael Turquette PLL_RATE(1104000000, 46, 1, 0), 232738f66d3SMichael Turquette PLL_RATE(1128000000, 47, 1, 0), 233738f66d3SMichael Turquette PLL_RATE(1152000000, 48, 1, 0), 234738f66d3SMichael Turquette PLL_RATE(1176000000, 49, 1, 0), 235738f66d3SMichael Turquette PLL_RATE(1200000000, 50, 1, 0), 236738f66d3SMichael Turquette PLL_RATE(1224000000, 51, 1, 0), 237738f66d3SMichael Turquette PLL_RATE(1248000000, 52, 1, 0), 238738f66d3SMichael Turquette PLL_RATE(1272000000, 53, 1, 0), 239738f66d3SMichael Turquette PLL_RATE(1296000000, 54, 1, 0), 240738f66d3SMichael Turquette PLL_RATE(1320000000, 55, 1, 0), 241738f66d3SMichael Turquette PLL_RATE(1344000000, 56, 1, 0), 242738f66d3SMichael Turquette PLL_RATE(1368000000, 57, 1, 0), 243738f66d3SMichael Turquette PLL_RATE(1392000000, 58, 1, 0), 244738f66d3SMichael Turquette PLL_RATE(1416000000, 59, 1, 0), 245738f66d3SMichael Turquette PLL_RATE(1440000000, 60, 1, 0), 246738f66d3SMichael Turquette PLL_RATE(1464000000, 61, 1, 0), 247738f66d3SMichael Turquette PLL_RATE(1488000000, 62, 1, 0), 248738f66d3SMichael Turquette { /* sentinel */ }, 249738f66d3SMichael Turquette }; 250738f66d3SMichael Turquette 251738f66d3SMichael Turquette static const struct clk_div_table cpu_div_table[] = { 252738f66d3SMichael Turquette { .val = 1, .div = 1 }, 253738f66d3SMichael Turquette { .val = 2, .div = 2 }, 254738f66d3SMichael Turquette { .val = 3, .div = 3 }, 255738f66d3SMichael Turquette { .val = 2, .div = 4 }, 256738f66d3SMichael Turquette { .val = 3, .div = 6 }, 257738f66d3SMichael Turquette { .val = 4, .div = 8 }, 258738f66d3SMichael Turquette { .val = 5, .div = 10 }, 259738f66d3SMichael Turquette { .val = 6, .div = 12 }, 260738f66d3SMichael Turquette { .val = 7, .div = 14 }, 261738f66d3SMichael Turquette { .val = 8, .div = 16 }, 262738f66d3SMichael Turquette { /* sentinel */ }, 263738f66d3SMichael Turquette }; 264738f66d3SMichael Turquette 265738f66d3SMichael Turquette static struct meson_clk_pll gxbb_fixed_pll = { 266738f66d3SMichael Turquette .m = { 267738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL, 268738f66d3SMichael Turquette .shift = 0, 269738f66d3SMichael Turquette .width = 9, 270738f66d3SMichael Turquette }, 271738f66d3SMichael Turquette .n = { 272738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL, 273738f66d3SMichael Turquette .shift = 9, 274738f66d3SMichael Turquette .width = 5, 275738f66d3SMichael Turquette }, 276738f66d3SMichael Turquette .od = { 277738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL, 278738f66d3SMichael Turquette .shift = 16, 279738f66d3SMichael Turquette .width = 2, 280738f66d3SMichael Turquette }, 281738f66d3SMichael Turquette .lock = &clk_lock, 282738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 283738f66d3SMichael Turquette .name = "fixed_pll", 284738f66d3SMichael Turquette .ops = &meson_clk_pll_ro_ops, 285738f66d3SMichael Turquette .parent_names = (const char *[]){ "xtal" }, 286738f66d3SMichael Turquette .num_parents = 1, 287738f66d3SMichael Turquette .flags = CLK_GET_RATE_NOCACHE, 288738f66d3SMichael Turquette }, 289738f66d3SMichael Turquette }; 290738f66d3SMichael Turquette 291738f66d3SMichael Turquette static struct meson_clk_pll gxbb_hdmi_pll = { 292738f66d3SMichael Turquette .m = { 293738f66d3SMichael Turquette .reg_off = HHI_HDMI_PLL_CNTL, 294738f66d3SMichael Turquette .shift = 0, 295738f66d3SMichael Turquette .width = 9, 296738f66d3SMichael Turquette }, 297738f66d3SMichael Turquette .n = { 298738f66d3SMichael Turquette .reg_off = HHI_HDMI_PLL_CNTL, 299738f66d3SMichael Turquette .shift = 9, 300738f66d3SMichael Turquette .width = 5, 301738f66d3SMichael Turquette }, 302738f66d3SMichael Turquette .frac = { 303738f66d3SMichael Turquette .reg_off = HHI_HDMI_PLL_CNTL2, 304738f66d3SMichael Turquette .shift = 0, 305738f66d3SMichael Turquette .width = 12, 306738f66d3SMichael Turquette }, 307738f66d3SMichael Turquette .od = { 308738f66d3SMichael Turquette .reg_off = HHI_HDMI_PLL_CNTL2, 309738f66d3SMichael Turquette .shift = 16, 310738f66d3SMichael Turquette .width = 2, 311738f66d3SMichael Turquette }, 312738f66d3SMichael Turquette .od2 = { 313738f66d3SMichael Turquette .reg_off = HHI_HDMI_PLL_CNTL2, 314738f66d3SMichael Turquette .shift = 22, 315738f66d3SMichael Turquette .width = 2, 316738f66d3SMichael Turquette }, 317738f66d3SMichael Turquette .lock = &clk_lock, 318738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 319738f66d3SMichael Turquette .name = "hdmi_pll", 320738f66d3SMichael Turquette .ops = &meson_clk_pll_ro_ops, 321738f66d3SMichael Turquette .parent_names = (const char *[]){ "xtal" }, 322738f66d3SMichael Turquette .num_parents = 1, 323738f66d3SMichael Turquette .flags = CLK_GET_RATE_NOCACHE, 324738f66d3SMichael Turquette }, 325738f66d3SMichael Turquette }; 326738f66d3SMichael Turquette 327738f66d3SMichael Turquette static struct meson_clk_pll gxbb_sys_pll = { 328738f66d3SMichael Turquette .m = { 329738f66d3SMichael Turquette .reg_off = HHI_SYS_PLL_CNTL, 330738f66d3SMichael Turquette .shift = 0, 331738f66d3SMichael Turquette .width = 9, 332738f66d3SMichael Turquette }, 333738f66d3SMichael Turquette .n = { 334738f66d3SMichael Turquette .reg_off = HHI_SYS_PLL_CNTL, 335738f66d3SMichael Turquette .shift = 9, 336738f66d3SMichael Turquette .width = 5, 337738f66d3SMichael Turquette }, 338738f66d3SMichael Turquette .od = { 339738f66d3SMichael Turquette .reg_off = HHI_SYS_PLL_CNTL, 340738f66d3SMichael Turquette .shift = 10, 341738f66d3SMichael Turquette .width = 2, 342738f66d3SMichael Turquette }, 343738f66d3SMichael Turquette .rate_table = sys_pll_rate_table, 344738f66d3SMichael Turquette .rate_count = ARRAY_SIZE(sys_pll_rate_table), 345738f66d3SMichael Turquette .lock = &clk_lock, 346738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 347738f66d3SMichael Turquette .name = "sys_pll", 348738f66d3SMichael Turquette .ops = &meson_clk_pll_ro_ops, 349738f66d3SMichael Turquette .parent_names = (const char *[]){ "xtal" }, 350738f66d3SMichael Turquette .num_parents = 1, 351738f66d3SMichael Turquette .flags = CLK_GET_RATE_NOCACHE, 352738f66d3SMichael Turquette }, 353738f66d3SMichael Turquette }; 354738f66d3SMichael Turquette 355738f66d3SMichael Turquette static struct meson_clk_pll gxbb_gp0_pll = { 356738f66d3SMichael Turquette .m = { 357738f66d3SMichael Turquette .reg_off = HHI_GP0_PLL_CNTL, 358738f66d3SMichael Turquette .shift = 0, 359738f66d3SMichael Turquette .width = 9, 360738f66d3SMichael Turquette }, 361738f66d3SMichael Turquette .n = { 362738f66d3SMichael Turquette .reg_off = HHI_GP0_PLL_CNTL, 363738f66d3SMichael Turquette .shift = 9, 364738f66d3SMichael Turquette .width = 5, 365738f66d3SMichael Turquette }, 366738f66d3SMichael Turquette .od = { 367738f66d3SMichael Turquette .reg_off = HHI_GP0_PLL_CNTL, 368738f66d3SMichael Turquette .shift = 16, 369738f66d3SMichael Turquette .width = 2, 370738f66d3SMichael Turquette }, 371738f66d3SMichael Turquette .rate_table = gp0_pll_rate_table, 372738f66d3SMichael Turquette .rate_count = ARRAY_SIZE(gp0_pll_rate_table), 373738f66d3SMichael Turquette .lock = &clk_lock, 374738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 375738f66d3SMichael Turquette .name = "gp0_pll", 376738f66d3SMichael Turquette .ops = &meson_clk_pll_ops, 377738f66d3SMichael Turquette .parent_names = (const char *[]){ "xtal" }, 378738f66d3SMichael Turquette .num_parents = 1, 379738f66d3SMichael Turquette .flags = CLK_GET_RATE_NOCACHE, 380738f66d3SMichael Turquette }, 381738f66d3SMichael Turquette }; 382738f66d3SMichael Turquette 383738f66d3SMichael Turquette static struct clk_fixed_factor gxbb_fclk_div2 = { 384738f66d3SMichael Turquette .mult = 1, 385738f66d3SMichael Turquette .div = 2, 386738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 387738f66d3SMichael Turquette .name = "fclk_div2", 388738f66d3SMichael Turquette .ops = &clk_fixed_factor_ops, 389738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 390738f66d3SMichael Turquette .num_parents = 1, 391738f66d3SMichael Turquette }, 392738f66d3SMichael Turquette }; 393738f66d3SMichael Turquette 394738f66d3SMichael Turquette static struct clk_fixed_factor gxbb_fclk_div3 = { 395738f66d3SMichael Turquette .mult = 1, 396738f66d3SMichael Turquette .div = 3, 397738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 398738f66d3SMichael Turquette .name = "fclk_div3", 399738f66d3SMichael Turquette .ops = &clk_fixed_factor_ops, 400738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 401738f66d3SMichael Turquette .num_parents = 1, 402738f66d3SMichael Turquette }, 403738f66d3SMichael Turquette }; 404738f66d3SMichael Turquette 405738f66d3SMichael Turquette static struct clk_fixed_factor gxbb_fclk_div4 = { 406738f66d3SMichael Turquette .mult = 1, 407738f66d3SMichael Turquette .div = 4, 408738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 409738f66d3SMichael Turquette .name = "fclk_div4", 410738f66d3SMichael Turquette .ops = &clk_fixed_factor_ops, 411738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 412738f66d3SMichael Turquette .num_parents = 1, 413738f66d3SMichael Turquette }, 414738f66d3SMichael Turquette }; 415738f66d3SMichael Turquette 416738f66d3SMichael Turquette static struct clk_fixed_factor gxbb_fclk_div5 = { 417738f66d3SMichael Turquette .mult = 1, 418738f66d3SMichael Turquette .div = 5, 419738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 420738f66d3SMichael Turquette .name = "fclk_div5", 421738f66d3SMichael Turquette .ops = &clk_fixed_factor_ops, 422738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 423738f66d3SMichael Turquette .num_parents = 1, 424738f66d3SMichael Turquette }, 425738f66d3SMichael Turquette }; 426738f66d3SMichael Turquette 427738f66d3SMichael Turquette static struct clk_fixed_factor gxbb_fclk_div7 = { 428738f66d3SMichael Turquette .mult = 1, 429738f66d3SMichael Turquette .div = 7, 430738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 431738f66d3SMichael Turquette .name = "fclk_div7", 432738f66d3SMichael Turquette .ops = &clk_fixed_factor_ops, 433738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 434738f66d3SMichael Turquette .num_parents = 1, 435738f66d3SMichael Turquette }, 436738f66d3SMichael Turquette }; 437738f66d3SMichael Turquette 438738f66d3SMichael Turquette static struct meson_clk_mpll gxbb_mpll0 = { 439738f66d3SMichael Turquette .sdm = { 440738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL7, 441738f66d3SMichael Turquette .shift = 0, 442738f66d3SMichael Turquette .width = 14, 443738f66d3SMichael Turquette }, 444738f66d3SMichael Turquette .n2 = { 445738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL7, 446738f66d3SMichael Turquette .shift = 16, 447738f66d3SMichael Turquette .width = 9, 448738f66d3SMichael Turquette }, 449738f66d3SMichael Turquette .lock = &clk_lock, 450738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 451738f66d3SMichael Turquette .name = "mpll0", 452738f66d3SMichael Turquette .ops = &meson_clk_mpll_ro_ops, 453738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 454738f66d3SMichael Turquette .num_parents = 1, 455738f66d3SMichael Turquette }, 456738f66d3SMichael Turquette }; 457738f66d3SMichael Turquette 458738f66d3SMichael Turquette static struct meson_clk_mpll gxbb_mpll1 = { 459738f66d3SMichael Turquette .sdm = { 460738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL8, 461738f66d3SMichael Turquette .shift = 0, 462738f66d3SMichael Turquette .width = 14, 463738f66d3SMichael Turquette }, 464738f66d3SMichael Turquette .n2 = { 465738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL8, 466738f66d3SMichael Turquette .shift = 16, 467738f66d3SMichael Turquette .width = 9, 468738f66d3SMichael Turquette }, 469738f66d3SMichael Turquette .lock = &clk_lock, 470738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 471738f66d3SMichael Turquette .name = "mpll1", 472738f66d3SMichael Turquette .ops = &meson_clk_mpll_ro_ops, 473738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 474738f66d3SMichael Turquette .num_parents = 1, 475738f66d3SMichael Turquette }, 476738f66d3SMichael Turquette }; 477738f66d3SMichael Turquette 478738f66d3SMichael Turquette static struct meson_clk_mpll gxbb_mpll2 = { 479738f66d3SMichael Turquette .sdm = { 480738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL9, 481738f66d3SMichael Turquette .shift = 0, 482738f66d3SMichael Turquette .width = 14, 483738f66d3SMichael Turquette }, 484738f66d3SMichael Turquette .n2 = { 485738f66d3SMichael Turquette .reg_off = HHI_MPLL_CNTL9, 486738f66d3SMichael Turquette .shift = 16, 487738f66d3SMichael Turquette .width = 9, 488738f66d3SMichael Turquette }, 489738f66d3SMichael Turquette .lock = &clk_lock, 490738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 491738f66d3SMichael Turquette .name = "mpll2", 492738f66d3SMichael Turquette .ops = &meson_clk_mpll_ro_ops, 493738f66d3SMichael Turquette .parent_names = (const char *[]){ "fixed_pll" }, 494738f66d3SMichael Turquette .num_parents = 1, 495738f66d3SMichael Turquette }, 496738f66d3SMichael Turquette }; 497738f66d3SMichael Turquette 498738f66d3SMichael Turquette /* 499738f66d3SMichael Turquette * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL 500738f66d3SMichael Turquette * post-dividers and should be modeled with their respective PLLs via the 501738f66d3SMichael Turquette * forthcoming coordinated clock rates feature 502738f66d3SMichael Turquette */ 503738f66d3SMichael Turquette static struct meson_clk_cpu gxbb_cpu_clk = { 504738f66d3SMichael Turquette .reg_off = HHI_SYS_CPU_CLK_CNTL1, 505738f66d3SMichael Turquette .div_table = cpu_div_table, 506738f66d3SMichael Turquette .clk_nb.notifier_call = meson_clk_cpu_notifier_cb, 507738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 508738f66d3SMichael Turquette .name = "cpu_clk", 509738f66d3SMichael Turquette .ops = &meson_clk_cpu_ops, 510738f66d3SMichael Turquette .parent_names = (const char *[]){ "sys_pll" }, 511738f66d3SMichael Turquette .num_parents = 1, 512738f66d3SMichael Turquette }, 513738f66d3SMichael Turquette }; 514738f66d3SMichael Turquette 515738f66d3SMichael Turquette static u32 mux_table_clk81[] = { 6, 5, 7 }; 516738f66d3SMichael Turquette 517738f66d3SMichael Turquette static struct clk_mux gxbb_mpeg_clk_sel = { 518738f66d3SMichael Turquette .reg = (void *)HHI_MPEG_CLK_CNTL, 519738f66d3SMichael Turquette .mask = 0x7, 520738f66d3SMichael Turquette .shift = 12, 521738f66d3SMichael Turquette .flags = CLK_MUX_READ_ONLY, 522738f66d3SMichael Turquette .table = mux_table_clk81, 523738f66d3SMichael Turquette .lock = &clk_lock, 524738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 525738f66d3SMichael Turquette .name = "mpeg_clk_sel", 526738f66d3SMichael Turquette .ops = &clk_mux_ro_ops, 527738f66d3SMichael Turquette /* 528738f66d3SMichael Turquette * FIXME bits 14:12 selects from 8 possible parents: 529738f66d3SMichael Turquette * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 530738f66d3SMichael Turquette * fclk_div4, fclk_div3, fclk_div5 531738f66d3SMichael Turquette */ 532738f66d3SMichael Turquette .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", 533738f66d3SMichael Turquette "fclk_div5" }, 534738f66d3SMichael Turquette .num_parents = 3, 535738f66d3SMichael Turquette .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED), 536738f66d3SMichael Turquette }, 537738f66d3SMichael Turquette }; 538738f66d3SMichael Turquette 539738f66d3SMichael Turquette static struct clk_divider gxbb_mpeg_clk_div = { 540738f66d3SMichael Turquette .reg = (void *)HHI_MPEG_CLK_CNTL, 541738f66d3SMichael Turquette .shift = 0, 542738f66d3SMichael Turquette .width = 7, 543738f66d3SMichael Turquette .lock = &clk_lock, 544738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 545738f66d3SMichael Turquette .name = "mpeg_clk_div", 546738f66d3SMichael Turquette .ops = &clk_divider_ops, 547738f66d3SMichael Turquette .parent_names = (const char *[]){ "mpeg_clk_sel" }, 548738f66d3SMichael Turquette .num_parents = 1, 549738f66d3SMichael Turquette .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), 550738f66d3SMichael Turquette }, 551738f66d3SMichael Turquette }; 552738f66d3SMichael Turquette 553738f66d3SMichael Turquette /* the mother of dragons^W gates */ 554738f66d3SMichael Turquette static struct clk_gate gxbb_clk81 = { 555738f66d3SMichael Turquette .reg = (void *)HHI_MPEG_CLK_CNTL, 556738f66d3SMichael Turquette .bit_idx = 7, 557738f66d3SMichael Turquette .lock = &clk_lock, 558738f66d3SMichael Turquette .hw.init = &(struct clk_init_data){ 559738f66d3SMichael Turquette .name = "clk81", 560738f66d3SMichael Turquette .ops = &clk_gate_ops, 561738f66d3SMichael Turquette .parent_names = (const char *[]){ "mpeg_clk_div" }, 562738f66d3SMichael Turquette .num_parents = 1, 563738f66d3SMichael Turquette .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL), 564738f66d3SMichael Turquette }, 565738f66d3SMichael Turquette }; 566738f66d3SMichael Turquette 56733d0fcdfSMartin Blumenstingl static struct clk_mux gxbb_sar_adc_clk_sel = { 56833d0fcdfSMartin Blumenstingl .reg = (void *)HHI_SAR_CLK_CNTL, 56933d0fcdfSMartin Blumenstingl .mask = 0x3, 57033d0fcdfSMartin Blumenstingl .shift = 9, 57133d0fcdfSMartin Blumenstingl .lock = &clk_lock, 57233d0fcdfSMartin Blumenstingl .hw.init = &(struct clk_init_data){ 57333d0fcdfSMartin Blumenstingl .name = "sar_adc_clk_sel", 57433d0fcdfSMartin Blumenstingl .ops = &clk_mux_ops, 57533d0fcdfSMartin Blumenstingl /* NOTE: The datasheet doesn't list the parents for bit 10 */ 57633d0fcdfSMartin Blumenstingl .parent_names = (const char *[]){ "xtal", "clk81", }, 57733d0fcdfSMartin Blumenstingl .num_parents = 2, 57833d0fcdfSMartin Blumenstingl }, 57933d0fcdfSMartin Blumenstingl }; 58033d0fcdfSMartin Blumenstingl 58133d0fcdfSMartin Blumenstingl static struct clk_divider gxbb_sar_adc_clk_div = { 58233d0fcdfSMartin Blumenstingl .reg = (void *)HHI_SAR_CLK_CNTL, 58333d0fcdfSMartin Blumenstingl .shift = 0, 58433d0fcdfSMartin Blumenstingl .width = 8, 58533d0fcdfSMartin Blumenstingl .lock = &clk_lock, 58633d0fcdfSMartin Blumenstingl .hw.init = &(struct clk_init_data){ 58733d0fcdfSMartin Blumenstingl .name = "sar_adc_clk_div", 58833d0fcdfSMartin Blumenstingl .ops = &clk_divider_ops, 58933d0fcdfSMartin Blumenstingl .parent_names = (const char *[]){ "sar_adc_clk_sel" }, 59033d0fcdfSMartin Blumenstingl .num_parents = 1, 59133d0fcdfSMartin Blumenstingl }, 59233d0fcdfSMartin Blumenstingl }; 59333d0fcdfSMartin Blumenstingl 59433d0fcdfSMartin Blumenstingl static struct clk_gate gxbb_sar_adc_clk = { 59533d0fcdfSMartin Blumenstingl .reg = (void *)HHI_SAR_CLK_CNTL, 59633d0fcdfSMartin Blumenstingl .bit_idx = 8, 59733d0fcdfSMartin Blumenstingl .lock = &clk_lock, 59833d0fcdfSMartin Blumenstingl .hw.init = &(struct clk_init_data){ 59933d0fcdfSMartin Blumenstingl .name = "sar_adc_clk", 60033d0fcdfSMartin Blumenstingl .ops = &clk_gate_ops, 60133d0fcdfSMartin Blumenstingl .parent_names = (const char *[]){ "sar_adc_clk_div" }, 60233d0fcdfSMartin Blumenstingl .num_parents = 1, 60333d0fcdfSMartin Blumenstingl .flags = CLK_SET_RATE_PARENT, 60433d0fcdfSMartin Blumenstingl }, 60533d0fcdfSMartin Blumenstingl }; 60633d0fcdfSMartin Blumenstingl 607738f66d3SMichael Turquette /* Everything Else (EE) domain gates */ 6087ba64d82SAlexander Müller static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); 6097ba64d82SAlexander Müller static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); 6107ba64d82SAlexander Müller static MESON_GATE(gxbb_isa, HHI_GCLK_MPEG0, 5); 6117ba64d82SAlexander Müller static MESON_GATE(gxbb_pl301, HHI_GCLK_MPEG0, 6); 6127ba64d82SAlexander Müller static MESON_GATE(gxbb_periphs, HHI_GCLK_MPEG0, 7); 6137ba64d82SAlexander Müller static MESON_GATE(gxbb_spicc, HHI_GCLK_MPEG0, 8); 6147ba64d82SAlexander Müller static MESON_GATE(gxbb_i2c, HHI_GCLK_MPEG0, 9); 6157ba64d82SAlexander Müller static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG0, 10); 6167ba64d82SAlexander Müller static MESON_GATE(gxbb_smart_card, HHI_GCLK_MPEG0, 11); 6177ba64d82SAlexander Müller static MESON_GATE(gxbb_rng0, HHI_GCLK_MPEG0, 12); 6187ba64d82SAlexander Müller static MESON_GATE(gxbb_uart0, HHI_GCLK_MPEG0, 13); 6197ba64d82SAlexander Müller static MESON_GATE(gxbb_sdhc, HHI_GCLK_MPEG0, 14); 6207ba64d82SAlexander Müller static MESON_GATE(gxbb_stream, HHI_GCLK_MPEG0, 15); 6217ba64d82SAlexander Müller static MESON_GATE(gxbb_async_fifo, HHI_GCLK_MPEG0, 16); 6227ba64d82SAlexander Müller static MESON_GATE(gxbb_sdio, HHI_GCLK_MPEG0, 17); 6237ba64d82SAlexander Müller static MESON_GATE(gxbb_abuf, HHI_GCLK_MPEG0, 18); 6247ba64d82SAlexander Müller static MESON_GATE(gxbb_hiu_iface, HHI_GCLK_MPEG0, 19); 6257ba64d82SAlexander Müller static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23); 6267ba64d82SAlexander Müller static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24); 6277ba64d82SAlexander Müller static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25); 6287ba64d82SAlexander Müller static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26); 6297ba64d82SAlexander Müller static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30); 630738f66d3SMichael Turquette 6317ba64d82SAlexander Müller static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2); 6327ba64d82SAlexander Müller static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3); 6337ba64d82SAlexander Müller static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4); 6347ba64d82SAlexander Müller static MESON_GATE(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6); 6357ba64d82SAlexander Müller static MESON_GATE(gxbb_iec958, HHI_GCLK_MPEG1, 7); 6367ba64d82SAlexander Müller static MESON_GATE(gxbb_i2s_out, HHI_GCLK_MPEG1, 8); 6377ba64d82SAlexander Müller static MESON_GATE(gxbb_amclk, HHI_GCLK_MPEG1, 9); 6387ba64d82SAlexander Müller static MESON_GATE(gxbb_aififo2, HHI_GCLK_MPEG1, 10); 6397ba64d82SAlexander Müller static MESON_GATE(gxbb_mixer, HHI_GCLK_MPEG1, 11); 6407ba64d82SAlexander Müller static MESON_GATE(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12); 6417ba64d82SAlexander Müller static MESON_GATE(gxbb_adc, HHI_GCLK_MPEG1, 13); 6427ba64d82SAlexander Müller static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14); 6437ba64d82SAlexander Müller static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15); 6447ba64d82SAlexander Müller static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16); 6457ba64d82SAlexander Müller static MESON_GATE(gxbb_g2d, HHI_GCLK_MPEG1, 20); 6467ba64d82SAlexander Müller static MESON_GATE(gxbb_usb0, HHI_GCLK_MPEG1, 21); 6477ba64d82SAlexander Müller static MESON_GATE(gxbb_usb1, HHI_GCLK_MPEG1, 22); 6487ba64d82SAlexander Müller static MESON_GATE(gxbb_reset, HHI_GCLK_MPEG1, 23); 6497ba64d82SAlexander Müller static MESON_GATE(gxbb_nand, HHI_GCLK_MPEG1, 24); 6507ba64d82SAlexander Müller static MESON_GATE(gxbb_dos_parser, HHI_GCLK_MPEG1, 25); 6517ba64d82SAlexander Müller static MESON_GATE(gxbb_usb, HHI_GCLK_MPEG1, 26); 6527ba64d82SAlexander Müller static MESON_GATE(gxbb_vdin1, HHI_GCLK_MPEG1, 28); 6537ba64d82SAlexander Müller static MESON_GATE(gxbb_ahb_arb0, HHI_GCLK_MPEG1, 29); 6547ba64d82SAlexander Müller static MESON_GATE(gxbb_efuse, HHI_GCLK_MPEG1, 30); 6557ba64d82SAlexander Müller static MESON_GATE(gxbb_boot_rom, HHI_GCLK_MPEG1, 31); 656738f66d3SMichael Turquette 6577ba64d82SAlexander Müller static MESON_GATE(gxbb_ahb_data_bus, HHI_GCLK_MPEG2, 1); 6587ba64d82SAlexander Müller static MESON_GATE(gxbb_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); 6597ba64d82SAlexander Müller static MESON_GATE(gxbb_hdmi_intr_sync, HHI_GCLK_MPEG2, 3); 6607ba64d82SAlexander Müller static MESON_GATE(gxbb_hdmi_pclk, HHI_GCLK_MPEG2, 4); 6617ba64d82SAlexander Müller static MESON_GATE(gxbb_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8); 6627ba64d82SAlexander Müller static MESON_GATE(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); 6637ba64d82SAlexander Müller static MESON_GATE(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11); 6647ba64d82SAlexander Müller static MESON_GATE(gxbb_dvin, HHI_GCLK_MPEG2, 12); 6657ba64d82SAlexander Müller static MESON_GATE(gxbb_uart2, HHI_GCLK_MPEG2, 15); 6667ba64d82SAlexander Müller static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG2, 22); 6677ba64d82SAlexander Müller static MESON_GATE(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25); 6687ba64d82SAlexander Müller static MESON_GATE(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 6697ba64d82SAlexander Müller static MESON_GATE(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29); 670738f66d3SMichael Turquette 6717ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_venci0, HHI_GCLK_OTHER, 1); 6727ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_venci1, HHI_GCLK_OTHER, 2); 6737ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_vencp0, HHI_GCLK_OTHER, 3); 6747ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_vencp1, HHI_GCLK_OTHER, 4); 6757ba64d82SAlexander Müller static MESON_GATE(gxbb_gclk_venci_int0, HHI_GCLK_OTHER, 8); 6767ba64d82SAlexander Müller static MESON_GATE(gxbb_gclk_vencp_int, HHI_GCLK_OTHER, 9); 6777ba64d82SAlexander Müller static MESON_GATE(gxbb_dac_clk, HHI_GCLK_OTHER, 10); 6787ba64d82SAlexander Müller static MESON_GATE(gxbb_aoclk_gate, HHI_GCLK_OTHER, 14); 6797ba64d82SAlexander Müller static MESON_GATE(gxbb_iec958_gate, HHI_GCLK_OTHER, 16); 6807ba64d82SAlexander Müller static MESON_GATE(gxbb_enc480p, HHI_GCLK_OTHER, 20); 6817ba64d82SAlexander Müller static MESON_GATE(gxbb_rng1, HHI_GCLK_OTHER, 21); 6827ba64d82SAlexander Müller static MESON_GATE(gxbb_gclk_venci_int1, HHI_GCLK_OTHER, 22); 6837ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_venclmcc, HHI_GCLK_OTHER, 24); 6847ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk2_vencl, HHI_GCLK_OTHER, 25); 6857ba64d82SAlexander Müller static MESON_GATE(gxbb_vclk_other, HHI_GCLK_OTHER, 26); 6867ba64d82SAlexander Müller static MESON_GATE(gxbb_edp, HHI_GCLK_OTHER, 31); 687738f66d3SMichael Turquette 688738f66d3SMichael Turquette /* Always On (AO) domain gates */ 689738f66d3SMichael Turquette 6907ba64d82SAlexander Müller static MESON_GATE(gxbb_ao_media_cpu, HHI_GCLK_AO, 0); 6917ba64d82SAlexander Müller static MESON_GATE(gxbb_ao_ahb_sram, HHI_GCLK_AO, 1); 6927ba64d82SAlexander Müller static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2); 6937ba64d82SAlexander Müller static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3); 6947ba64d82SAlexander Müller static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4); 695738f66d3SMichael Turquette 696738f66d3SMichael Turquette /* Array of all clocks provided by this provider */ 697738f66d3SMichael Turquette 698738f66d3SMichael Turquette static struct clk_hw_onecell_data gxbb_hw_onecell_data = { 699738f66d3SMichael Turquette .hws = { 700738f66d3SMichael Turquette [CLKID_SYS_PLL] = &gxbb_sys_pll.hw, 701738f66d3SMichael Turquette [CLKID_CPUCLK] = &gxbb_cpu_clk.hw, 702738f66d3SMichael Turquette [CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw, 703738f66d3SMichael Turquette [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw, 704738f66d3SMichael Turquette [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw, 705738f66d3SMichael Turquette [CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw, 706738f66d3SMichael Turquette [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, 707738f66d3SMichael Turquette [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, 708738f66d3SMichael Turquette [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, 709738f66d3SMichael Turquette [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, 710738f66d3SMichael Turquette [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, 711738f66d3SMichael Turquette [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, 712738f66d3SMichael Turquette [CLKID_CLK81] = &gxbb_clk81.hw, 713738f66d3SMichael Turquette [CLKID_MPLL0] = &gxbb_mpll0.hw, 714738f66d3SMichael Turquette [CLKID_MPLL1] = &gxbb_mpll1.hw, 715738f66d3SMichael Turquette [CLKID_MPLL2] = &gxbb_mpll2.hw, 716738f66d3SMichael Turquette [CLKID_DDR] = &gxbb_ddr.hw, 717738f66d3SMichael Turquette [CLKID_DOS] = &gxbb_dos.hw, 718738f66d3SMichael Turquette [CLKID_ISA] = &gxbb_isa.hw, 719738f66d3SMichael Turquette [CLKID_PL301] = &gxbb_pl301.hw, 720738f66d3SMichael Turquette [CLKID_PERIPHS] = &gxbb_periphs.hw, 721738f66d3SMichael Turquette [CLKID_SPICC] = &gxbb_spicc.hw, 722738f66d3SMichael Turquette [CLKID_I2C] = &gxbb_i2c.hw, 723738f66d3SMichael Turquette [CLKID_SAR_ADC] = &gxbb_sar_adc.hw, 724738f66d3SMichael Turquette [CLKID_SMART_CARD] = &gxbb_smart_card.hw, 725738f66d3SMichael Turquette [CLKID_RNG0] = &gxbb_rng0.hw, 726738f66d3SMichael Turquette [CLKID_UART0] = &gxbb_uart0.hw, 727738f66d3SMichael Turquette [CLKID_SDHC] = &gxbb_sdhc.hw, 728738f66d3SMichael Turquette [CLKID_STREAM] = &gxbb_stream.hw, 729738f66d3SMichael Turquette [CLKID_ASYNC_FIFO] = &gxbb_async_fifo.hw, 730738f66d3SMichael Turquette [CLKID_SDIO] = &gxbb_sdio.hw, 731738f66d3SMichael Turquette [CLKID_ABUF] = &gxbb_abuf.hw, 732738f66d3SMichael Turquette [CLKID_HIU_IFACE] = &gxbb_hiu_iface.hw, 733738f66d3SMichael Turquette [CLKID_ASSIST_MISC] = &gxbb_assist_misc.hw, 734738f66d3SMichael Turquette [CLKID_SPI] = &gxbb_spi.hw, 735738f66d3SMichael Turquette [CLKID_I2S_SPDIF] = &gxbb_i2s_spdif.hw, 736738f66d3SMichael Turquette [CLKID_ETH] = &gxbb_eth.hw, 737738f66d3SMichael Turquette [CLKID_DEMUX] = &gxbb_demux.hw, 738738f66d3SMichael Turquette [CLKID_AIU_GLUE] = &gxbb_aiu_glue.hw, 739738f66d3SMichael Turquette [CLKID_IEC958] = &gxbb_iec958.hw, 740738f66d3SMichael Turquette [CLKID_I2S_OUT] = &gxbb_i2s_out.hw, 741738f66d3SMichael Turquette [CLKID_AMCLK] = &gxbb_amclk.hw, 742738f66d3SMichael Turquette [CLKID_AIFIFO2] = &gxbb_aififo2.hw, 743738f66d3SMichael Turquette [CLKID_MIXER] = &gxbb_mixer.hw, 744738f66d3SMichael Turquette [CLKID_MIXER_IFACE] = &gxbb_mixer_iface.hw, 745738f66d3SMichael Turquette [CLKID_ADC] = &gxbb_adc.hw, 746738f66d3SMichael Turquette [CLKID_BLKMV] = &gxbb_blkmv.hw, 747738f66d3SMichael Turquette [CLKID_AIU] = &gxbb_aiu.hw, 748738f66d3SMichael Turquette [CLKID_UART1] = &gxbb_uart1.hw, 749738f66d3SMichael Turquette [CLKID_G2D] = &gxbb_g2d.hw, 750738f66d3SMichael Turquette [CLKID_USB0] = &gxbb_usb0.hw, 751738f66d3SMichael Turquette [CLKID_USB1] = &gxbb_usb1.hw, 752738f66d3SMichael Turquette [CLKID_RESET] = &gxbb_reset.hw, 753738f66d3SMichael Turquette [CLKID_NAND] = &gxbb_nand.hw, 754738f66d3SMichael Turquette [CLKID_DOS_PARSER] = &gxbb_dos_parser.hw, 755738f66d3SMichael Turquette [CLKID_USB] = &gxbb_usb.hw, 756738f66d3SMichael Turquette [CLKID_VDIN1] = &gxbb_vdin1.hw, 757738f66d3SMichael Turquette [CLKID_AHB_ARB0] = &gxbb_ahb_arb0.hw, 758738f66d3SMichael Turquette [CLKID_EFUSE] = &gxbb_efuse.hw, 759738f66d3SMichael Turquette [CLKID_BOOT_ROM] = &gxbb_boot_rom.hw, 760738f66d3SMichael Turquette [CLKID_AHB_DATA_BUS] = &gxbb_ahb_data_bus.hw, 761738f66d3SMichael Turquette [CLKID_AHB_CTRL_BUS] = &gxbb_ahb_ctrl_bus.hw, 762738f66d3SMichael Turquette [CLKID_HDMI_INTR_SYNC] = &gxbb_hdmi_intr_sync.hw, 763738f66d3SMichael Turquette [CLKID_HDMI_PCLK] = &gxbb_hdmi_pclk.hw, 764738f66d3SMichael Turquette [CLKID_USB1_DDR_BRIDGE] = &gxbb_usb1_ddr_bridge.hw, 765738f66d3SMichael Turquette [CLKID_USB0_DDR_BRIDGE] = &gxbb_usb0_ddr_bridge.hw, 766738f66d3SMichael Turquette [CLKID_MMC_PCLK] = &gxbb_mmc_pclk.hw, 767738f66d3SMichael Turquette [CLKID_DVIN] = &gxbb_dvin.hw, 768738f66d3SMichael Turquette [CLKID_UART2] = &gxbb_uart2.hw, 769738f66d3SMichael Turquette [CLKID_SANA] = &gxbb_sana.hw, 770738f66d3SMichael Turquette [CLKID_VPU_INTR] = &gxbb_vpu_intr.hw, 771738f66d3SMichael Turquette [CLKID_SEC_AHB_AHB3_BRIDGE] = &gxbb_sec_ahb_ahb3_bridge.hw, 772738f66d3SMichael Turquette [CLKID_CLK81_A53] = &gxbb_clk81_a53.hw, 773738f66d3SMichael Turquette [CLKID_VCLK2_VENCI0] = &gxbb_vclk2_venci0.hw, 774738f66d3SMichael Turquette [CLKID_VCLK2_VENCI1] = &gxbb_vclk2_venci1.hw, 775738f66d3SMichael Turquette [CLKID_VCLK2_VENCP0] = &gxbb_vclk2_vencp0.hw, 776738f66d3SMichael Turquette [CLKID_VCLK2_VENCP1] = &gxbb_vclk2_vencp1.hw, 777738f66d3SMichael Turquette [CLKID_GCLK_VENCI_INT0] = &gxbb_gclk_venci_int0.hw, 778738f66d3SMichael Turquette [CLKID_GCLK_VENCI_INT] = &gxbb_gclk_vencp_int.hw, 779738f66d3SMichael Turquette [CLKID_DAC_CLK] = &gxbb_dac_clk.hw, 780738f66d3SMichael Turquette [CLKID_AOCLK_GATE] = &gxbb_aoclk_gate.hw, 781738f66d3SMichael Turquette [CLKID_IEC958_GATE] = &gxbb_iec958_gate.hw, 782738f66d3SMichael Turquette [CLKID_ENC480P] = &gxbb_enc480p.hw, 783738f66d3SMichael Turquette [CLKID_RNG1] = &gxbb_rng1.hw, 784738f66d3SMichael Turquette [CLKID_GCLK_VENCI_INT1] = &gxbb_gclk_venci_int1.hw, 785738f66d3SMichael Turquette [CLKID_VCLK2_VENCLMCC] = &gxbb_vclk2_venclmcc.hw, 786738f66d3SMichael Turquette [CLKID_VCLK2_VENCL] = &gxbb_vclk2_vencl.hw, 787738f66d3SMichael Turquette [CLKID_VCLK_OTHER] = &gxbb_vclk_other.hw, 788738f66d3SMichael Turquette [CLKID_EDP] = &gxbb_edp.hw, 789738f66d3SMichael Turquette [CLKID_AO_MEDIA_CPU] = &gxbb_ao_media_cpu.hw, 790738f66d3SMichael Turquette [CLKID_AO_AHB_SRAM] = &gxbb_ao_ahb_sram.hw, 791738f66d3SMichael Turquette [CLKID_AO_AHB_BUS] = &gxbb_ao_ahb_bus.hw, 792738f66d3SMichael Turquette [CLKID_AO_IFACE] = &gxbb_ao_iface.hw, 793738f66d3SMichael Turquette [CLKID_AO_I2C] = &gxbb_ao_i2c.hw, 79433608dcdSKevin Hilman [CLKID_SD_EMMC_A] = &gxbb_emmc_a.hw, 79533608dcdSKevin Hilman [CLKID_SD_EMMC_B] = &gxbb_emmc_b.hw, 79633608dcdSKevin Hilman [CLKID_SD_EMMC_C] = &gxbb_emmc_c.hw, 79733d0fcdfSMartin Blumenstingl [CLKID_SAR_ADC_CLK] = &gxbb_sar_adc_clk.hw, 79833d0fcdfSMartin Blumenstingl [CLKID_SAR_ADC_SEL] = &gxbb_sar_adc_clk_sel.hw, 79933d0fcdfSMartin Blumenstingl [CLKID_SAR_ADC_DIV] = &gxbb_sar_adc_clk_div.hw, 800738f66d3SMichael Turquette }, 801738f66d3SMichael Turquette .num = NR_CLKS, 802738f66d3SMichael Turquette }; 803738f66d3SMichael Turquette 804738f66d3SMichael Turquette /* Convenience tables to populate base addresses in .probe */ 805738f66d3SMichael Turquette 806738f66d3SMichael Turquette static struct meson_clk_pll *const gxbb_clk_plls[] = { 807738f66d3SMichael Turquette &gxbb_fixed_pll, 808738f66d3SMichael Turquette &gxbb_hdmi_pll, 809738f66d3SMichael Turquette &gxbb_sys_pll, 810738f66d3SMichael Turquette &gxbb_gp0_pll, 811738f66d3SMichael Turquette }; 812738f66d3SMichael Turquette 813738f66d3SMichael Turquette static struct meson_clk_mpll *const gxbb_clk_mplls[] = { 814738f66d3SMichael Turquette &gxbb_mpll0, 815738f66d3SMichael Turquette &gxbb_mpll1, 816738f66d3SMichael Turquette &gxbb_mpll2, 817738f66d3SMichael Turquette }; 818738f66d3SMichael Turquette 819f7e3a826SJerome Brunet static struct clk_gate *const gxbb_clk_gates[] = { 820738f66d3SMichael Turquette &gxbb_clk81, 821738f66d3SMichael Turquette &gxbb_ddr, 822738f66d3SMichael Turquette &gxbb_dos, 823738f66d3SMichael Turquette &gxbb_isa, 824738f66d3SMichael Turquette &gxbb_pl301, 825738f66d3SMichael Turquette &gxbb_periphs, 826738f66d3SMichael Turquette &gxbb_spicc, 827738f66d3SMichael Turquette &gxbb_i2c, 828738f66d3SMichael Turquette &gxbb_sar_adc, 829738f66d3SMichael Turquette &gxbb_smart_card, 830738f66d3SMichael Turquette &gxbb_rng0, 831738f66d3SMichael Turquette &gxbb_uart0, 832738f66d3SMichael Turquette &gxbb_sdhc, 833738f66d3SMichael Turquette &gxbb_stream, 834738f66d3SMichael Turquette &gxbb_async_fifo, 835738f66d3SMichael Turquette &gxbb_sdio, 836738f66d3SMichael Turquette &gxbb_abuf, 837738f66d3SMichael Turquette &gxbb_hiu_iface, 838738f66d3SMichael Turquette &gxbb_assist_misc, 839738f66d3SMichael Turquette &gxbb_spi, 840738f66d3SMichael Turquette &gxbb_i2s_spdif, 841738f66d3SMichael Turquette &gxbb_eth, 842738f66d3SMichael Turquette &gxbb_demux, 843738f66d3SMichael Turquette &gxbb_aiu_glue, 844738f66d3SMichael Turquette &gxbb_iec958, 845738f66d3SMichael Turquette &gxbb_i2s_out, 846738f66d3SMichael Turquette &gxbb_amclk, 847738f66d3SMichael Turquette &gxbb_aififo2, 848738f66d3SMichael Turquette &gxbb_mixer, 849738f66d3SMichael Turquette &gxbb_mixer_iface, 850738f66d3SMichael Turquette &gxbb_adc, 851738f66d3SMichael Turquette &gxbb_blkmv, 852738f66d3SMichael Turquette &gxbb_aiu, 853738f66d3SMichael Turquette &gxbb_uart1, 854738f66d3SMichael Turquette &gxbb_g2d, 855738f66d3SMichael Turquette &gxbb_usb0, 856738f66d3SMichael Turquette &gxbb_usb1, 857738f66d3SMichael Turquette &gxbb_reset, 858738f66d3SMichael Turquette &gxbb_nand, 859738f66d3SMichael Turquette &gxbb_dos_parser, 860738f66d3SMichael Turquette &gxbb_usb, 861738f66d3SMichael Turquette &gxbb_vdin1, 862738f66d3SMichael Turquette &gxbb_ahb_arb0, 863738f66d3SMichael Turquette &gxbb_efuse, 864738f66d3SMichael Turquette &gxbb_boot_rom, 865738f66d3SMichael Turquette &gxbb_ahb_data_bus, 866738f66d3SMichael Turquette &gxbb_ahb_ctrl_bus, 867738f66d3SMichael Turquette &gxbb_hdmi_intr_sync, 868738f66d3SMichael Turquette &gxbb_hdmi_pclk, 869738f66d3SMichael Turquette &gxbb_usb1_ddr_bridge, 870738f66d3SMichael Turquette &gxbb_usb0_ddr_bridge, 871738f66d3SMichael Turquette &gxbb_mmc_pclk, 872738f66d3SMichael Turquette &gxbb_dvin, 873738f66d3SMichael Turquette &gxbb_uart2, 874738f66d3SMichael Turquette &gxbb_sana, 875738f66d3SMichael Turquette &gxbb_vpu_intr, 876738f66d3SMichael Turquette &gxbb_sec_ahb_ahb3_bridge, 877738f66d3SMichael Turquette &gxbb_clk81_a53, 878738f66d3SMichael Turquette &gxbb_vclk2_venci0, 879738f66d3SMichael Turquette &gxbb_vclk2_venci1, 880738f66d3SMichael Turquette &gxbb_vclk2_vencp0, 881738f66d3SMichael Turquette &gxbb_vclk2_vencp1, 882738f66d3SMichael Turquette &gxbb_gclk_venci_int0, 883738f66d3SMichael Turquette &gxbb_gclk_vencp_int, 884738f66d3SMichael Turquette &gxbb_dac_clk, 885738f66d3SMichael Turquette &gxbb_aoclk_gate, 886738f66d3SMichael Turquette &gxbb_iec958_gate, 887738f66d3SMichael Turquette &gxbb_enc480p, 888738f66d3SMichael Turquette &gxbb_rng1, 889738f66d3SMichael Turquette &gxbb_gclk_venci_int1, 890738f66d3SMichael Turquette &gxbb_vclk2_venclmcc, 891738f66d3SMichael Turquette &gxbb_vclk2_vencl, 892738f66d3SMichael Turquette &gxbb_vclk_other, 893738f66d3SMichael Turquette &gxbb_edp, 894738f66d3SMichael Turquette &gxbb_ao_media_cpu, 895738f66d3SMichael Turquette &gxbb_ao_ahb_sram, 896738f66d3SMichael Turquette &gxbb_ao_ahb_bus, 897738f66d3SMichael Turquette &gxbb_ao_iface, 898738f66d3SMichael Turquette &gxbb_ao_i2c, 89933608dcdSKevin Hilman &gxbb_emmc_a, 90033608dcdSKevin Hilman &gxbb_emmc_b, 90133608dcdSKevin Hilman &gxbb_emmc_c, 90233d0fcdfSMartin Blumenstingl &gxbb_sar_adc_clk, 903738f66d3SMichael Turquette }; 904738f66d3SMichael Turquette 905738f66d3SMichael Turquette static int gxbb_clkc_probe(struct platform_device *pdev) 906738f66d3SMichael Turquette { 907738f66d3SMichael Turquette void __iomem *clk_base; 908738f66d3SMichael Turquette int ret, clkid, i; 909738f66d3SMichael Turquette struct clk_hw *parent_hw; 910738f66d3SMichael Turquette struct clk *parent_clk; 911738f66d3SMichael Turquette struct device *dev = &pdev->dev; 912738f66d3SMichael Turquette 913738f66d3SMichael Turquette /* Generic clocks and PLLs */ 914738f66d3SMichael Turquette clk_base = of_iomap(dev->of_node, 0); 915738f66d3SMichael Turquette if (!clk_base) { 916738f66d3SMichael Turquette pr_err("%s: Unable to map clk base\n", __func__); 917738f66d3SMichael Turquette return -ENXIO; 918738f66d3SMichael Turquette } 919738f66d3SMichael Turquette 920738f66d3SMichael Turquette /* Populate base address for PLLs */ 921738f66d3SMichael Turquette for (i = 0; i < ARRAY_SIZE(gxbb_clk_plls); i++) 922738f66d3SMichael Turquette gxbb_clk_plls[i]->base = clk_base; 923738f66d3SMichael Turquette 924738f66d3SMichael Turquette /* Populate base address for MPLLs */ 925738f66d3SMichael Turquette for (i = 0; i < ARRAY_SIZE(gxbb_clk_mplls); i++) 926738f66d3SMichael Turquette gxbb_clk_mplls[i]->base = clk_base; 927738f66d3SMichael Turquette 928738f66d3SMichael Turquette /* Populate the base address for CPU clk */ 929738f66d3SMichael Turquette gxbb_cpu_clk.base = clk_base; 930738f66d3SMichael Turquette 931738f66d3SMichael Turquette /* Populate the base address for the MPEG clks */ 932738f66d3SMichael Turquette gxbb_mpeg_clk_sel.reg = clk_base + (u64)gxbb_mpeg_clk_sel.reg; 933738f66d3SMichael Turquette gxbb_mpeg_clk_div.reg = clk_base + (u64)gxbb_mpeg_clk_div.reg; 934738f66d3SMichael Turquette 93533d0fcdfSMartin Blumenstingl /* Populate the base address for the SAR ADC clks */ 93633d0fcdfSMartin Blumenstingl gxbb_sar_adc_clk_sel.reg = clk_base + (u64)gxbb_sar_adc_clk_sel.reg; 93733d0fcdfSMartin Blumenstingl gxbb_sar_adc_clk_div.reg = clk_base + (u64)gxbb_sar_adc_clk_div.reg; 93833d0fcdfSMartin Blumenstingl 939738f66d3SMichael Turquette /* Populate base address for gates */ 940738f66d3SMichael Turquette for (i = 0; i < ARRAY_SIZE(gxbb_clk_gates); i++) 941738f66d3SMichael Turquette gxbb_clk_gates[i]->reg = clk_base + 942738f66d3SMichael Turquette (u64)gxbb_clk_gates[i]->reg; 943738f66d3SMichael Turquette 944738f66d3SMichael Turquette /* 945738f66d3SMichael Turquette * register all clks 946738f66d3SMichael Turquette */ 947738f66d3SMichael Turquette for (clkid = 0; clkid < NR_CLKS; clkid++) { 948738f66d3SMichael Turquette ret = devm_clk_hw_register(dev, gxbb_hw_onecell_data.hws[clkid]); 949738f66d3SMichael Turquette if (ret) 950738f66d3SMichael Turquette goto iounmap; 951738f66d3SMichael Turquette } 952738f66d3SMichael Turquette 953738f66d3SMichael Turquette /* 954738f66d3SMichael Turquette * Register CPU clk notifier 955738f66d3SMichael Turquette * 956738f66d3SMichael Turquette * FIXME this is wrong for a lot of reasons. First, the muxes should be 957738f66d3SMichael Turquette * struct clk_hw objects. Second, we shouldn't program the muxes in 958738f66d3SMichael Turquette * notifier handlers. The tricky programming sequence will be handled 959738f66d3SMichael Turquette * by the forthcoming coordinated clock rates mechanism once that 960738f66d3SMichael Turquette * feature is released. 961738f66d3SMichael Turquette * 962738f66d3SMichael Turquette * Furthermore, looking up the parent this way is terrible. At some 963738f66d3SMichael Turquette * point we will stop allocating a default struct clk when registering 964738f66d3SMichael Turquette * a new clk_hw, and this hack will no longer work. Releasing the ccr 965738f66d3SMichael Turquette * feature before that time solves the problem :-) 966738f66d3SMichael Turquette */ 967738f66d3SMichael Turquette parent_hw = clk_hw_get_parent(&gxbb_cpu_clk.hw); 968738f66d3SMichael Turquette parent_clk = parent_hw->clk; 969738f66d3SMichael Turquette ret = clk_notifier_register(parent_clk, &gxbb_cpu_clk.clk_nb); 970738f66d3SMichael Turquette if (ret) { 971738f66d3SMichael Turquette pr_err("%s: failed to register clock notifier for cpu_clk\n", 972738f66d3SMichael Turquette __func__); 973738f66d3SMichael Turquette goto iounmap; 974738f66d3SMichael Turquette } 975738f66d3SMichael Turquette 976738f66d3SMichael Turquette return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 977738f66d3SMichael Turquette &gxbb_hw_onecell_data); 978738f66d3SMichael Turquette 979738f66d3SMichael Turquette iounmap: 980738f66d3SMichael Turquette iounmap(clk_base); 981738f66d3SMichael Turquette return ret; 982738f66d3SMichael Turquette } 983738f66d3SMichael Turquette 984738f66d3SMichael Turquette static const struct of_device_id gxbb_clkc_match_table[] = { 985738f66d3SMichael Turquette { .compatible = "amlogic,gxbb-clkc" }, 986738f66d3SMichael Turquette { } 987738f66d3SMichael Turquette }; 988738f66d3SMichael Turquette 989738f66d3SMichael Turquette static struct platform_driver gxbb_driver = { 990738f66d3SMichael Turquette .probe = gxbb_clkc_probe, 991738f66d3SMichael Turquette .driver = { 992738f66d3SMichael Turquette .name = "gxbb-clkc", 993738f66d3SMichael Turquette .of_match_table = gxbb_clkc_match_table, 994738f66d3SMichael Turquette }, 995738f66d3SMichael Turquette }; 996738f66d3SMichael Turquette 99700746f10SWei Yongjun builtin_platform_driver(gxbb_driver); 998