19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2763c5bd0SIcenowy Zheng /* 3763c5bd0SIcenowy Zheng * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> 4763c5bd0SIcenowy Zheng */ 5763c5bd0SIcenowy Zheng 6763c5bd0SIcenowy Zheng #include <linux/clk.h> 7763c5bd0SIcenowy Zheng #include <linux/clk-provider.h> 8763c5bd0SIcenowy Zheng #include <linux/of_address.h> 9763c5bd0SIcenowy Zheng #include <linux/of_platform.h> 10763c5bd0SIcenowy Zheng #include <linux/platform_device.h> 11763c5bd0SIcenowy Zheng #include <linux/reset.h> 12763c5bd0SIcenowy Zheng 13763c5bd0SIcenowy Zheng #include "ccu_common.h" 14763c5bd0SIcenowy Zheng #include "ccu_div.h" 15763c5bd0SIcenowy Zheng #include "ccu_gate.h" 16763c5bd0SIcenowy Zheng #include "ccu_reset.h" 17763c5bd0SIcenowy Zheng 18763c5bd0SIcenowy Zheng #include "ccu-sun8i-de2.h" 19763c5bd0SIcenowy Zheng 20763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(bus_mixer0_clk, "bus-mixer0", "bus-de", 21763c5bd0SIcenowy Zheng 0x04, BIT(0), 0); 22763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1", "bus-de", 23763c5bd0SIcenowy Zheng 0x04, BIT(1), 0); 24763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(bus_wb_clk, "bus-wb", "bus-de", 25763c5bd0SIcenowy Zheng 0x04, BIT(2), 0); 2656808da9SJernej Skrabec static SUNXI_CCU_GATE(bus_rot_clk, "bus-rot", "bus-de", 2756808da9SJernej Skrabec 0x04, BIT(3), 0); 28763c5bd0SIcenowy Zheng 29763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(mixer0_clk, "mixer0", "mixer0-div", 30763c5bd0SIcenowy Zheng 0x00, BIT(0), CLK_SET_RATE_PARENT); 31763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(mixer1_clk, "mixer1", "mixer1-div", 32763c5bd0SIcenowy Zheng 0x00, BIT(1), CLK_SET_RATE_PARENT); 33763c5bd0SIcenowy Zheng static SUNXI_CCU_GATE(wb_clk, "wb", "wb-div", 34763c5bd0SIcenowy Zheng 0x00, BIT(2), CLK_SET_RATE_PARENT); 3556808da9SJernej Skrabec static SUNXI_CCU_GATE(rot_clk, "rot", "rot-div", 3656808da9SJernej Skrabec 0x00, BIT(3), CLK_SET_RATE_PARENT); 37763c5bd0SIcenowy Zheng 38763c5bd0SIcenowy Zheng static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4, 39763c5bd0SIcenowy Zheng CLK_SET_RATE_PARENT); 4019368d99SIcenowy Zheng static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4, 4119368d99SIcenowy Zheng CLK_SET_RATE_PARENT); 42763c5bd0SIcenowy Zheng static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4, 43763c5bd0SIcenowy Zheng CLK_SET_RATE_PARENT); 4456808da9SJernej Skrabec static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4, 4556808da9SJernej Skrabec CLK_SET_RATE_PARENT); 46763c5bd0SIcenowy Zheng 47553c7d5bSMaxime Ripard static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4, 48553c7d5bSMaxime Ripard CLK_SET_RATE_PARENT); 49553c7d5bSMaxime Ripard static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4, 50553c7d5bSMaxime Ripard CLK_SET_RATE_PARENT); 51553c7d5bSMaxime Ripard static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4, 52553c7d5bSMaxime Ripard CLK_SET_RATE_PARENT); 53553c7d5bSMaxime Ripard 5456808da9SJernej Skrabec static struct ccu_common *sun50i_h6_de3_clks[] = { 5556808da9SJernej Skrabec &mixer0_clk.common, 5656808da9SJernej Skrabec &mixer1_clk.common, 5756808da9SJernej Skrabec &wb_clk.common, 5856808da9SJernej Skrabec 5956808da9SJernej Skrabec &bus_mixer0_clk.common, 6056808da9SJernej Skrabec &bus_mixer1_clk.common, 6156808da9SJernej Skrabec &bus_wb_clk.common, 6256808da9SJernej Skrabec 6356808da9SJernej Skrabec &mixer0_div_clk.common, 6456808da9SJernej Skrabec &mixer1_div_clk.common, 6556808da9SJernej Skrabec &wb_div_clk.common, 6656808da9SJernej Skrabec 6756808da9SJernej Skrabec &bus_rot_clk.common, 6856808da9SJernej Skrabec &rot_clk.common, 6956808da9SJernej Skrabec &rot_div_clk.common, 7056808da9SJernej Skrabec }; 7156808da9SJernej Skrabec 72763c5bd0SIcenowy Zheng static struct ccu_common *sun8i_a83t_de2_clks[] = { 73763c5bd0SIcenowy Zheng &mixer0_clk.common, 74763c5bd0SIcenowy Zheng &mixer1_clk.common, 75763c5bd0SIcenowy Zheng &wb_clk.common, 76763c5bd0SIcenowy Zheng 77763c5bd0SIcenowy Zheng &bus_mixer0_clk.common, 78763c5bd0SIcenowy Zheng &bus_mixer1_clk.common, 79763c5bd0SIcenowy Zheng &bus_wb_clk.common, 80763c5bd0SIcenowy Zheng 81553c7d5bSMaxime Ripard &mixer0_div_a83_clk.common, 82553c7d5bSMaxime Ripard &mixer1_div_a83_clk.common, 83553c7d5bSMaxime Ripard &wb_div_a83_clk.common, 84763c5bd0SIcenowy Zheng }; 85763c5bd0SIcenowy Zheng 8619368d99SIcenowy Zheng static struct ccu_common *sun8i_h3_de2_clks[] = { 8719368d99SIcenowy Zheng &mixer0_clk.common, 8819368d99SIcenowy Zheng &mixer1_clk.common, 8919368d99SIcenowy Zheng &wb_clk.common, 9019368d99SIcenowy Zheng 9119368d99SIcenowy Zheng &bus_mixer0_clk.common, 9219368d99SIcenowy Zheng &bus_mixer1_clk.common, 9319368d99SIcenowy Zheng &bus_wb_clk.common, 9419368d99SIcenowy Zheng 9519368d99SIcenowy Zheng &mixer0_div_clk.common, 9619368d99SIcenowy Zheng &mixer1_div_clk.common, 9719368d99SIcenowy Zheng &wb_div_clk.common, 9819368d99SIcenowy Zheng }; 9919368d99SIcenowy Zheng 100763c5bd0SIcenowy Zheng static struct ccu_common *sun8i_v3s_de2_clks[] = { 101763c5bd0SIcenowy Zheng &mixer0_clk.common, 102763c5bd0SIcenowy Zheng &wb_clk.common, 103763c5bd0SIcenowy Zheng 104763c5bd0SIcenowy Zheng &bus_mixer0_clk.common, 105763c5bd0SIcenowy Zheng &bus_wb_clk.common, 106763c5bd0SIcenowy Zheng 107763c5bd0SIcenowy Zheng &mixer0_div_clk.common, 108763c5bd0SIcenowy Zheng &wb_div_clk.common, 109763c5bd0SIcenowy Zheng }; 110763c5bd0SIcenowy Zheng 111*b4bbce66SJernej Skrabec static struct ccu_common *sun50i_a64_de2_clks[] = { 112*b4bbce66SJernej Skrabec &mixer0_clk.common, 113*b4bbce66SJernej Skrabec &mixer1_clk.common, 114*b4bbce66SJernej Skrabec &wb_clk.common, 115*b4bbce66SJernej Skrabec 116*b4bbce66SJernej Skrabec &bus_mixer0_clk.common, 117*b4bbce66SJernej Skrabec &bus_mixer1_clk.common, 118*b4bbce66SJernej Skrabec &bus_wb_clk.common, 119*b4bbce66SJernej Skrabec 120*b4bbce66SJernej Skrabec &mixer0_div_clk.common, 121*b4bbce66SJernej Skrabec &mixer1_div_clk.common, 122*b4bbce66SJernej Skrabec &wb_div_clk.common, 123*b4bbce66SJernej Skrabec 124*b4bbce66SJernej Skrabec &bus_rot_clk.common, 125*b4bbce66SJernej Skrabec &rot_clk.common, 126*b4bbce66SJernej Skrabec &rot_div_clk.common, 127*b4bbce66SJernej Skrabec }; 128*b4bbce66SJernej Skrabec 129763c5bd0SIcenowy Zheng static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { 130763c5bd0SIcenowy Zheng .hws = { 131763c5bd0SIcenowy Zheng [CLK_MIXER0] = &mixer0_clk.common.hw, 132763c5bd0SIcenowy Zheng [CLK_MIXER1] = &mixer1_clk.common.hw, 133763c5bd0SIcenowy Zheng [CLK_WB] = &wb_clk.common.hw, 134763c5bd0SIcenowy Zheng 135763c5bd0SIcenowy Zheng [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, 136763c5bd0SIcenowy Zheng [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, 137763c5bd0SIcenowy Zheng [CLK_BUS_WB] = &bus_wb_clk.common.hw, 138763c5bd0SIcenowy Zheng 139553c7d5bSMaxime Ripard [CLK_MIXER0_DIV] = &mixer0_div_a83_clk.common.hw, 140553c7d5bSMaxime Ripard [CLK_MIXER1_DIV] = &mixer1_div_a83_clk.common.hw, 141553c7d5bSMaxime Ripard [CLK_WB_DIV] = &wb_div_a83_clk.common.hw, 142763c5bd0SIcenowy Zheng }, 14356808da9SJernej Skrabec .num = CLK_NUMBER_WITHOUT_ROT, 144763c5bd0SIcenowy Zheng }; 145763c5bd0SIcenowy Zheng 14619368d99SIcenowy Zheng static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = { 14719368d99SIcenowy Zheng .hws = { 14819368d99SIcenowy Zheng [CLK_MIXER0] = &mixer0_clk.common.hw, 14919368d99SIcenowy Zheng [CLK_MIXER1] = &mixer1_clk.common.hw, 15019368d99SIcenowy Zheng [CLK_WB] = &wb_clk.common.hw, 15119368d99SIcenowy Zheng 15219368d99SIcenowy Zheng [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, 15319368d99SIcenowy Zheng [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, 15419368d99SIcenowy Zheng [CLK_BUS_WB] = &bus_wb_clk.common.hw, 15519368d99SIcenowy Zheng 15619368d99SIcenowy Zheng [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, 15719368d99SIcenowy Zheng [CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw, 15819368d99SIcenowy Zheng [CLK_WB_DIV] = &wb_div_clk.common.hw, 15919368d99SIcenowy Zheng }, 16056808da9SJernej Skrabec .num = CLK_NUMBER_WITHOUT_ROT, 16119368d99SIcenowy Zheng }; 16219368d99SIcenowy Zheng 163763c5bd0SIcenowy Zheng static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = { 164763c5bd0SIcenowy Zheng .hws = { 165763c5bd0SIcenowy Zheng [CLK_MIXER0] = &mixer0_clk.common.hw, 166763c5bd0SIcenowy Zheng [CLK_WB] = &wb_clk.common.hw, 167763c5bd0SIcenowy Zheng 168763c5bd0SIcenowy Zheng [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, 169763c5bd0SIcenowy Zheng [CLK_BUS_WB] = &bus_wb_clk.common.hw, 170763c5bd0SIcenowy Zheng 171763c5bd0SIcenowy Zheng [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, 172763c5bd0SIcenowy Zheng [CLK_WB_DIV] = &wb_div_clk.common.hw, 173763c5bd0SIcenowy Zheng }, 17456808da9SJernej Skrabec .num = CLK_NUMBER_WITHOUT_ROT, 17556808da9SJernej Skrabec }; 17656808da9SJernej Skrabec 177*b4bbce66SJernej Skrabec static struct clk_hw_onecell_data sun50i_a64_de2_hw_clks = { 178*b4bbce66SJernej Skrabec .hws = { 179*b4bbce66SJernej Skrabec [CLK_MIXER0] = &mixer0_clk.common.hw, 180*b4bbce66SJernej Skrabec [CLK_MIXER1] = &mixer1_clk.common.hw, 181*b4bbce66SJernej Skrabec [CLK_WB] = &wb_clk.common.hw, 182*b4bbce66SJernej Skrabec [CLK_ROT] = &rot_clk.common.hw, 183*b4bbce66SJernej Skrabec 184*b4bbce66SJernej Skrabec [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, 185*b4bbce66SJernej Skrabec [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, 186*b4bbce66SJernej Skrabec [CLK_BUS_WB] = &bus_wb_clk.common.hw, 187*b4bbce66SJernej Skrabec [CLK_BUS_ROT] = &bus_rot_clk.common.hw, 188*b4bbce66SJernej Skrabec 189*b4bbce66SJernej Skrabec [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, 190*b4bbce66SJernej Skrabec [CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw, 191*b4bbce66SJernej Skrabec [CLK_WB_DIV] = &wb_div_clk.common.hw, 192*b4bbce66SJernej Skrabec [CLK_ROT_DIV] = &rot_div_clk.common.hw, 193*b4bbce66SJernej Skrabec }, 194*b4bbce66SJernej Skrabec .num = CLK_NUMBER_WITH_ROT, 195*b4bbce66SJernej Skrabec }; 196*b4bbce66SJernej Skrabec 19756808da9SJernej Skrabec static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = { 19856808da9SJernej Skrabec .hws = { 19956808da9SJernej Skrabec [CLK_MIXER0] = &mixer0_clk.common.hw, 20056808da9SJernej Skrabec [CLK_MIXER1] = &mixer1_clk.common.hw, 20156808da9SJernej Skrabec [CLK_WB] = &wb_clk.common.hw, 20256808da9SJernej Skrabec [CLK_ROT] = &rot_clk.common.hw, 20356808da9SJernej Skrabec 20456808da9SJernej Skrabec [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, 20556808da9SJernej Skrabec [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, 20656808da9SJernej Skrabec [CLK_BUS_WB] = &bus_wb_clk.common.hw, 20756808da9SJernej Skrabec [CLK_BUS_ROT] = &bus_rot_clk.common.hw, 20856808da9SJernej Skrabec 20956808da9SJernej Skrabec [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw, 21056808da9SJernej Skrabec [CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw, 21156808da9SJernej Skrabec [CLK_WB_DIV] = &wb_div_clk.common.hw, 21256808da9SJernej Skrabec [CLK_ROT_DIV] = &rot_div_clk.common.hw, 21356808da9SJernej Skrabec }, 21456808da9SJernej Skrabec .num = CLK_NUMBER_WITH_ROT, 215763c5bd0SIcenowy Zheng }; 216763c5bd0SIcenowy Zheng 217763c5bd0SIcenowy Zheng static struct ccu_reset_map sun8i_a83t_de2_resets[] = { 218763c5bd0SIcenowy Zheng [RST_MIXER0] = { 0x08, BIT(0) }, 219763c5bd0SIcenowy Zheng /* 220763c5bd0SIcenowy Zheng * For A83T, H3 and R40, mixer1 reset line is shared with wb, so 221763c5bd0SIcenowy Zheng * only RST_WB is exported here. 222763c5bd0SIcenowy Zheng * For V3s there's just no mixer1, so it also shares this struct. 223763c5bd0SIcenowy Zheng */ 224763c5bd0SIcenowy Zheng [RST_WB] = { 0x08, BIT(2) }, 225763c5bd0SIcenowy Zheng }; 226763c5bd0SIcenowy Zheng 227763c5bd0SIcenowy Zheng static struct ccu_reset_map sun50i_a64_de2_resets[] = { 228763c5bd0SIcenowy Zheng [RST_MIXER0] = { 0x08, BIT(0) }, 229763c5bd0SIcenowy Zheng [RST_MIXER1] = { 0x08, BIT(1) }, 230763c5bd0SIcenowy Zheng [RST_WB] = { 0x08, BIT(2) }, 231*b4bbce66SJernej Skrabec [RST_ROT] = { 0x08, BIT(3) }, 232763c5bd0SIcenowy Zheng }; 233763c5bd0SIcenowy Zheng 2342b48dcb7SJernej Skrabec static struct ccu_reset_map sun50i_h5_de2_resets[] = { 2352b48dcb7SJernej Skrabec [RST_MIXER0] = { 0x08, BIT(0) }, 2362b48dcb7SJernej Skrabec [RST_MIXER1] = { 0x08, BIT(1) }, 2372b48dcb7SJernej Skrabec [RST_WB] = { 0x08, BIT(2) }, 2382b48dcb7SJernej Skrabec }; 2392b48dcb7SJernej Skrabec 24056808da9SJernej Skrabec static struct ccu_reset_map sun50i_h6_de3_resets[] = { 24156808da9SJernej Skrabec [RST_MIXER0] = { 0x08, BIT(0) }, 24256808da9SJernej Skrabec [RST_MIXER1] = { 0x08, BIT(1) }, 24356808da9SJernej Skrabec [RST_WB] = { 0x08, BIT(2) }, 24456808da9SJernej Skrabec [RST_ROT] = { 0x08, BIT(3) }, 24556808da9SJernej Skrabec }; 24656808da9SJernej Skrabec 247763c5bd0SIcenowy Zheng static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = { 248763c5bd0SIcenowy Zheng .ccu_clks = sun8i_a83t_de2_clks, 249763c5bd0SIcenowy Zheng .num_ccu_clks = ARRAY_SIZE(sun8i_a83t_de2_clks), 250763c5bd0SIcenowy Zheng 251763c5bd0SIcenowy Zheng .hw_clks = &sun8i_a83t_de2_hw_clks, 252763c5bd0SIcenowy Zheng 253763c5bd0SIcenowy Zheng .resets = sun8i_a83t_de2_resets, 254763c5bd0SIcenowy Zheng .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), 255763c5bd0SIcenowy Zheng }; 256763c5bd0SIcenowy Zheng 25719368d99SIcenowy Zheng static const struct sunxi_ccu_desc sun8i_h3_de2_clk_desc = { 25819368d99SIcenowy Zheng .ccu_clks = sun8i_h3_de2_clks, 25919368d99SIcenowy Zheng .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), 26019368d99SIcenowy Zheng 26119368d99SIcenowy Zheng .hw_clks = &sun8i_h3_de2_hw_clks, 26219368d99SIcenowy Zheng 26319368d99SIcenowy Zheng .resets = sun8i_a83t_de2_resets, 26419368d99SIcenowy Zheng .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), 26519368d99SIcenowy Zheng }; 26619368d99SIcenowy Zheng 267763c5bd0SIcenowy Zheng static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { 268*b4bbce66SJernej Skrabec .ccu_clks = sun50i_a64_de2_clks, 269*b4bbce66SJernej Skrabec .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks), 270763c5bd0SIcenowy Zheng 271*b4bbce66SJernej Skrabec .hw_clks = &sun50i_a64_de2_hw_clks, 272763c5bd0SIcenowy Zheng 273763c5bd0SIcenowy Zheng .resets = sun50i_a64_de2_resets, 274763c5bd0SIcenowy Zheng .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), 275763c5bd0SIcenowy Zheng }; 276763c5bd0SIcenowy Zheng 2772b48dcb7SJernej Skrabec static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { 2782b48dcb7SJernej Skrabec .ccu_clks = sun8i_h3_de2_clks, 2792b48dcb7SJernej Skrabec .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), 2802b48dcb7SJernej Skrabec 2812b48dcb7SJernej Skrabec .hw_clks = &sun8i_h3_de2_hw_clks, 2822b48dcb7SJernej Skrabec 2832b48dcb7SJernej Skrabec .resets = sun50i_h5_de2_resets, 2842b48dcb7SJernej Skrabec .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), 2852b48dcb7SJernej Skrabec }; 2862b48dcb7SJernej Skrabec 28756808da9SJernej Skrabec static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = { 28856808da9SJernej Skrabec .ccu_clks = sun50i_h6_de3_clks, 28956808da9SJernej Skrabec .num_ccu_clks = ARRAY_SIZE(sun50i_h6_de3_clks), 29056808da9SJernej Skrabec 29156808da9SJernej Skrabec .hw_clks = &sun50i_h6_de3_hw_clks, 29256808da9SJernej Skrabec 29356808da9SJernej Skrabec .resets = sun50i_h6_de3_resets, 29456808da9SJernej Skrabec .num_resets = ARRAY_SIZE(sun50i_h6_de3_resets), 29556808da9SJernej Skrabec }; 29656808da9SJernej Skrabec 297763c5bd0SIcenowy Zheng static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { 298763c5bd0SIcenowy Zheng .ccu_clks = sun8i_v3s_de2_clks, 299763c5bd0SIcenowy Zheng .num_ccu_clks = ARRAY_SIZE(sun8i_v3s_de2_clks), 300763c5bd0SIcenowy Zheng 301763c5bd0SIcenowy Zheng .hw_clks = &sun8i_v3s_de2_hw_clks, 302763c5bd0SIcenowy Zheng 303763c5bd0SIcenowy Zheng .resets = sun8i_a83t_de2_resets, 304763c5bd0SIcenowy Zheng .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), 305763c5bd0SIcenowy Zheng }; 306763c5bd0SIcenowy Zheng 307763c5bd0SIcenowy Zheng static int sunxi_de2_clk_probe(struct platform_device *pdev) 308763c5bd0SIcenowy Zheng { 309763c5bd0SIcenowy Zheng struct resource *res; 310763c5bd0SIcenowy Zheng struct clk *bus_clk, *mod_clk; 311763c5bd0SIcenowy Zheng struct reset_control *rstc; 312763c5bd0SIcenowy Zheng void __iomem *reg; 313763c5bd0SIcenowy Zheng const struct sunxi_ccu_desc *ccu_desc; 314763c5bd0SIcenowy Zheng int ret; 315763c5bd0SIcenowy Zheng 316763c5bd0SIcenowy Zheng ccu_desc = of_device_get_match_data(&pdev->dev); 317763c5bd0SIcenowy Zheng if (!ccu_desc) 318763c5bd0SIcenowy Zheng return -EINVAL; 319763c5bd0SIcenowy Zheng 320763c5bd0SIcenowy Zheng res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 321763c5bd0SIcenowy Zheng reg = devm_ioremap_resource(&pdev->dev, res); 322763c5bd0SIcenowy Zheng if (IS_ERR(reg)) 323763c5bd0SIcenowy Zheng return PTR_ERR(reg); 324763c5bd0SIcenowy Zheng 325763c5bd0SIcenowy Zheng bus_clk = devm_clk_get(&pdev->dev, "bus"); 326763c5bd0SIcenowy Zheng if (IS_ERR(bus_clk)) { 327763c5bd0SIcenowy Zheng ret = PTR_ERR(bus_clk); 328763c5bd0SIcenowy Zheng if (ret != -EPROBE_DEFER) 329763c5bd0SIcenowy Zheng dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret); 330763c5bd0SIcenowy Zheng return ret; 331763c5bd0SIcenowy Zheng } 332763c5bd0SIcenowy Zheng 333763c5bd0SIcenowy Zheng mod_clk = devm_clk_get(&pdev->dev, "mod"); 334763c5bd0SIcenowy Zheng if (IS_ERR(mod_clk)) { 335763c5bd0SIcenowy Zheng ret = PTR_ERR(mod_clk); 336763c5bd0SIcenowy Zheng if (ret != -EPROBE_DEFER) 337763c5bd0SIcenowy Zheng dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret); 338763c5bd0SIcenowy Zheng return ret; 339763c5bd0SIcenowy Zheng } 340763c5bd0SIcenowy Zheng 341763c5bd0SIcenowy Zheng rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 342763c5bd0SIcenowy Zheng if (IS_ERR(rstc)) { 3431f6d640cSWei Yongjun ret = PTR_ERR(rstc); 344763c5bd0SIcenowy Zheng if (ret != -EPROBE_DEFER) 345763c5bd0SIcenowy Zheng dev_err(&pdev->dev, 346763c5bd0SIcenowy Zheng "Couldn't get reset control: %d\n", ret); 347763c5bd0SIcenowy Zheng return ret; 348763c5bd0SIcenowy Zheng } 349763c5bd0SIcenowy Zheng 350763c5bd0SIcenowy Zheng /* The clocks need to be enabled for us to access the registers */ 351763c5bd0SIcenowy Zheng ret = clk_prepare_enable(bus_clk); 352763c5bd0SIcenowy Zheng if (ret) { 353763c5bd0SIcenowy Zheng dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret); 354763c5bd0SIcenowy Zheng return ret; 355763c5bd0SIcenowy Zheng } 356763c5bd0SIcenowy Zheng 357763c5bd0SIcenowy Zheng ret = clk_prepare_enable(mod_clk); 358763c5bd0SIcenowy Zheng if (ret) { 359763c5bd0SIcenowy Zheng dev_err(&pdev->dev, "Couldn't enable mod clk: %d\n", ret); 360763c5bd0SIcenowy Zheng goto err_disable_bus_clk; 361763c5bd0SIcenowy Zheng } 362763c5bd0SIcenowy Zheng 363763c5bd0SIcenowy Zheng /* The reset control needs to be asserted for the controls to work */ 364763c5bd0SIcenowy Zheng ret = reset_control_deassert(rstc); 365763c5bd0SIcenowy Zheng if (ret) { 366763c5bd0SIcenowy Zheng dev_err(&pdev->dev, 367763c5bd0SIcenowy Zheng "Couldn't deassert reset control: %d\n", ret); 368763c5bd0SIcenowy Zheng goto err_disable_mod_clk; 369763c5bd0SIcenowy Zheng } 370763c5bd0SIcenowy Zheng 371763c5bd0SIcenowy Zheng ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); 372763c5bd0SIcenowy Zheng if (ret) 373763c5bd0SIcenowy Zheng goto err_assert_reset; 374763c5bd0SIcenowy Zheng 375763c5bd0SIcenowy Zheng return 0; 376763c5bd0SIcenowy Zheng 377763c5bd0SIcenowy Zheng err_assert_reset: 378763c5bd0SIcenowy Zheng reset_control_assert(rstc); 379763c5bd0SIcenowy Zheng err_disable_mod_clk: 380763c5bd0SIcenowy Zheng clk_disable_unprepare(mod_clk); 381763c5bd0SIcenowy Zheng err_disable_bus_clk: 382763c5bd0SIcenowy Zheng clk_disable_unprepare(bus_clk); 383763c5bd0SIcenowy Zheng return ret; 384763c5bd0SIcenowy Zheng } 385763c5bd0SIcenowy Zheng 386763c5bd0SIcenowy Zheng static const struct of_device_id sunxi_de2_clk_ids[] = { 387763c5bd0SIcenowy Zheng { 388763c5bd0SIcenowy Zheng .compatible = "allwinner,sun8i-a83t-de2-clk", 389763c5bd0SIcenowy Zheng .data = &sun8i_a83t_de2_clk_desc, 390763c5bd0SIcenowy Zheng }, 391763c5bd0SIcenowy Zheng { 39219368d99SIcenowy Zheng .compatible = "allwinner,sun8i-h3-de2-clk", 39319368d99SIcenowy Zheng .data = &sun8i_h3_de2_clk_desc, 39419368d99SIcenowy Zheng }, 39519368d99SIcenowy Zheng { 396763c5bd0SIcenowy Zheng .compatible = "allwinner,sun8i-v3s-de2-clk", 397763c5bd0SIcenowy Zheng .data = &sun8i_v3s_de2_clk_desc, 398763c5bd0SIcenowy Zheng }, 399763c5bd0SIcenowy Zheng { 40001951563SIcenowy Zheng .compatible = "allwinner,sun50i-a64-de2-clk", 40101951563SIcenowy Zheng .data = &sun50i_a64_de2_clk_desc, 40201951563SIcenowy Zheng }, 40301951563SIcenowy Zheng { 404763c5bd0SIcenowy Zheng .compatible = "allwinner,sun50i-h5-de2-clk", 4052b48dcb7SJernej Skrabec .data = &sun50i_h5_de2_clk_desc, 406763c5bd0SIcenowy Zheng }, 40756808da9SJernej Skrabec { 40856808da9SJernej Skrabec .compatible = "allwinner,sun50i-h6-de3-clk", 40956808da9SJernej Skrabec .data = &sun50i_h6_de3_clk_desc, 41056808da9SJernej Skrabec }, 411763c5bd0SIcenowy Zheng { } 412763c5bd0SIcenowy Zheng }; 413763c5bd0SIcenowy Zheng 414763c5bd0SIcenowy Zheng static struct platform_driver sunxi_de2_clk_driver = { 415763c5bd0SIcenowy Zheng .probe = sunxi_de2_clk_probe, 416763c5bd0SIcenowy Zheng .driver = { 417763c5bd0SIcenowy Zheng .name = "sunxi-de2-clks", 418763c5bd0SIcenowy Zheng .of_match_table = sunxi_de2_clk_ids, 419763c5bd0SIcenowy Zheng }, 420763c5bd0SIcenowy Zheng }; 421763c5bd0SIcenowy Zheng builtin_platform_driver(sunxi_de2_clk_driver); 422