···11+* Samsung Exynos4415 Clock Controller22+33+The Exynos4415 clock controller generates and supplies clock to various44+consumer devices within the Exynos4415 SoC.55+66+Required properties:77+88+- compatible: should be one of the following:99+ - "samsung,exynos4415-cmu" - for the main system clocks controller1010+ (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains).1111+ - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory1212+ Controller (DMC) domain clock controller.1313+1414+- reg: physical base address of the controller and length of memory mapped1515+ region.1616+1717+- #clock-cells: should be 1.1818+1919+Each clock is assigned an identifier and client nodes can use this identifier2020+to specify the clock which they consume.2121+2222+All available clocks are defined as preprocessor macros in2323+dt-bindings/clock/exynos4415.h header and can be used in device2424+tree sources.2525+2626+Example 1: An example of a clock controller node is listed below.2727+2828+ cmu: clock-controller@10030000 {2929+ compatible = "samsung,exynos4415-cmu";3030+ reg = <0x10030000 0x18000>;3131+ #clock-cells = <1>;3232+ };3333+3434+ cmu-dmc: clock-controller@105C0000 {3535+ compatible = "samsung,exynos4415-cmu-dmc";3636+ reg = <0x105C0000 0x3000>;3737+ #clock-cells = <1>;3838+ };
···11+* Samsung Exynos7 Clock Controller22+33+Exynos7 clock controller has various blocks which are instantiated44+independently from the device-tree. These clock controllers55+generate and supply clocks to various hardware blocks within66+the SoC.77+88+Each clock is assigned an identifier and client nodes can use99+this identifier to specify the clock which they consume. All1010+available clocks are defined as preprocessor macros in1111+dt-bindings/clock/exynos7-clk.h header and can be used in1212+device tree sources.1313+1414+External clocks:1515+1616+There are several clocks that are generated outside the SoC. It1717+is expected that they are defined using standard clock bindings1818+with following clock-output-names:1919+2020+ - "fin_pll" - PLL input clock from XXTI2121+2222+Required Properties for Clock Controller:2323+2424+ - compatible: clock controllers will use one of the following2525+ compatible strings to indicate the clock controller2626+ functionality.2727+2828+ - "samsung,exynos7-clock-topc"2929+ - "samsung,exynos7-clock-top0"3030+ - "samsung,exynos7-clock-top1"3131+ - "samsung,exynos7-clock-ccore"3232+ - "samsung,exynos7-clock-peric0"3333+ - "samsung,exynos7-clock-peric1"3434+ - "samsung,exynos7-clock-peris"3535+ - "samsung,exynos7-clock-fsys0"3636+ - "samsung,exynos7-clock-fsys1"3737+3838+ - reg: physical base address of the controller and the length of3939+ memory mapped region.4040+4141+ - #clock-cells: should be 1.4242+4343+ - clocks: list of clock identifiers which are fed as the input to4444+ the given clock controller. Please refer the next section to4545+ find the input clocks for a given controller.4646+4747+- clock-names: list of names of clocks which are fed as the input4848+ to the given clock controller.4949+5050+Input clocks for top0 clock controller:5151+ - fin_pll5252+ - dout_sclk_bus0_pll5353+ - dout_sclk_bus1_pll5454+ - dout_sclk_cc_pll5555+ - dout_sclk_mfc_pll5656+5757+Input clocks for top1 clock controller:5858+ - fin_pll5959+ - dout_sclk_bus0_pll6060+ - dout_sclk_bus1_pll6161+ - dout_sclk_cc_pll6262+ - dout_sclk_mfc_pll6363+6464+Input clocks for ccore clock controller:6565+ - fin_pll6666+ - dout_aclk_ccore_1336767+6868+Input clocks for peric0 clock controller:6969+ - fin_pll7070+ - dout_aclk_peric0_667171+ - sclk_uart07272+7373+Input clocks for peric1 clock controller:7474+ - fin_pll7575+ - dout_aclk_peric1_667676+ - sclk_uart17777+ - sclk_uart27878+ - sclk_uart37979+8080+Input clocks for peris clock controller:8181+ - fin_pll8282+ - dout_aclk_peris_668383+8484+Input clocks for fsys0 clock controller:8585+ - fin_pll8686+ - dout_aclk_fsys0_2008787+ - dout_sclk_mmc28888+8989+Input clocks for fsys1 clock controller:9090+ - fin_pll9191+ - dout_aclk_fsys1_2009292+ - dout_sclk_mmc09393+ - dout_sclk_mmc1
···1414#include <linux/syscore_ops.h>1515#include "clk.h"16161717+static LIST_HEAD(clock_reg_cache_list);1818+1719void samsung_clk_save(void __iomem *base,1820 struct samsung_clk_reg_dump *rd,1921 unsigned int num_regs)···314312 }315313316314 return clk_get_rate(clk);315315+}316316+317317+#ifdef CONFIG_PM_SLEEP318318+static int samsung_clk_suspend(void)319319+{320320+ struct samsung_clock_reg_cache *reg_cache;321321+322322+ list_for_each_entry(reg_cache, &clock_reg_cache_list, node)323323+ samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,324324+ reg_cache->rd_num);325325+ return 0;326326+}327327+328328+static void samsung_clk_resume(void)329329+{330330+ struct samsung_clock_reg_cache *reg_cache;331331+332332+ list_for_each_entry(reg_cache, &clock_reg_cache_list, node)333333+ samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump,334334+ reg_cache->rd_num);335335+}336336+337337+static struct syscore_ops samsung_clk_syscore_ops = {338338+ .suspend = samsung_clk_suspend,339339+ .resume = samsung_clk_resume,340340+};341341+342342+static void samsung_clk_sleep_init(void __iomem *reg_base,343343+ const unsigned long *rdump,344344+ unsigned long nr_rdump)345345+{346346+ struct samsung_clock_reg_cache *reg_cache;347347+348348+ reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache),349349+ GFP_KERNEL);350350+ if (!reg_cache)351351+ panic("could not allocate register reg_cache.\n");352352+ reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);353353+354354+ if (!reg_cache->rdump)355355+ panic("could not allocate register dump storage.\n");356356+357357+ if (list_empty(&clock_reg_cache_list))358358+ register_syscore_ops(&samsung_clk_syscore_ops);359359+360360+ reg_cache->reg_base = reg_base;361361+ reg_cache->rd_num = nr_rdump;362362+ list_add_tail(®_cache->node, &clock_reg_cache_list);363363+}364364+365365+#else366366+static void samsung_clk_sleep_init(void __iomem *reg_base,367367+ const unsigned long *rdump,368368+ unsigned long nr_rdump) {}369369+#endif370370+371371+/*372372+ * Common function which registers plls, muxes, dividers and gates373373+ * for each CMU. It also add CMU register list to register cache.374374+ */375375+void __init samsung_cmu_register_one(struct device_node *np,376376+ struct samsung_cmu_info *cmu)377377+{378378+ void __iomem *reg_base;379379+ struct samsung_clk_provider *ctx;380380+381381+ reg_base = of_iomap(np, 0);382382+ if (!reg_base)383383+ panic("%s: failed to map registers\n", __func__);384384+385385+ ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);386386+ if (!ctx)387387+ panic("%s: unable to alllocate ctx\n", __func__);388388+389389+ if (cmu->pll_clks)390390+ samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,391391+ reg_base);392392+ if (cmu->mux_clks)393393+ samsung_clk_register_mux(ctx, cmu->mux_clks,394394+ cmu->nr_mux_clks);395395+ if (cmu->div_clks)396396+ samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);397397+ if (cmu->gate_clks)398398+ samsung_clk_register_gate(ctx, cmu->gate_clks,399399+ cmu->nr_gate_clks);400400+ if (cmu->fixed_clks)401401+ samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,402402+ cmu->nr_fixed_clks);403403+ if (cmu->fixed_factor_clks)404404+ samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,405405+ cmu->nr_fixed_factor_clks);406406+ if (cmu->clk_regs)407407+ samsung_clk_sleep_init(reg_base, cmu->clk_regs,408408+ cmu->nr_clk_regs);409409+410410+ samsung_clk_of_add_provider(np, ctx);317411}
+37
drivers/clk/samsung/clk.h
···324324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \325325 _lock, _con, _rtable, _alias)326326327327+struct samsung_clock_reg_cache {328328+ struct list_head node;329329+ void __iomem *reg_base;330330+ struct samsung_clk_reg_dump *rdump;331331+ unsigned int rd_num;332332+};333333+334334+struct samsung_cmu_info {335335+ /* list of pll clocks and respective count */336336+ struct samsung_pll_clock *pll_clks;337337+ unsigned int nr_pll_clks;338338+ /* list of mux clocks and respective count */339339+ struct samsung_mux_clock *mux_clks;340340+ unsigned int nr_mux_clks;341341+ /* list of div clocks and respective count */342342+ struct samsung_div_clock *div_clks;343343+ unsigned int nr_div_clks;344344+ /* list of gate clocks and respective count */345345+ struct samsung_gate_clock *gate_clks;346346+ unsigned int nr_gate_clks;347347+ /* list of fixed clocks and respective count */348348+ struct samsung_fixed_rate_clock *fixed_clks;349349+ unsigned int nr_fixed_clks;350350+ /* list of fixed factor clocks and respective count */351351+ struct samsung_fixed_factor_clock *fixed_factor_clks;352352+ unsigned int nr_fixed_factor_clks;353353+ /* total number of clocks with IDs assigned*/354354+ unsigned int nr_clk_ids;355355+356356+ /* list and number of clocks registers */357357+ unsigned long *clk_regs;358358+ unsigned int nr_clk_regs;359359+};360360+327361extern struct samsung_clk_provider *__init samsung_clk_init(328362 struct device_node *np, void __iomem *base,329363 unsigned long nr_clks);···395361extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,396362 struct samsung_pll_clock *pll_list,397363 unsigned int nr_clk, void __iomem *base);364364+365365+extern void __init samsung_cmu_register_one(struct device_node *,366366+ struct samsung_cmu_info *);398367399368extern unsigned long _get_rate(const char *clk_name);400369