1*c6ed4d73SDavid Lechner // SPDX-License-Identifier: GPL-2.0 2*c6ed4d73SDavid Lechner /* 3*c6ed4d73SDavid Lechner * Clock driver for TI Davinci PSC controllers 4*c6ed4d73SDavid Lechner * 5*c6ed4d73SDavid Lechner * Copyright (C) 2018 David Lechner <david@lechnology.com> 6*c6ed4d73SDavid Lechner */ 7*c6ed4d73SDavid Lechner 8*c6ed4d73SDavid Lechner #ifndef __CLK_DAVINCI_PSC_H__ 9*c6ed4d73SDavid Lechner #define __CLK_DAVINCI_PSC_H__ 10*c6ed4d73SDavid Lechner 11*c6ed4d73SDavid Lechner #include <linux/clk-provider.h> 12*c6ed4d73SDavid Lechner #include <linux/types.h> 13*c6ed4d73SDavid Lechner 14*c6ed4d73SDavid Lechner /* PSC quirk flags */ 15*c6ed4d73SDavid Lechner #define LPSC_ALWAYS_ENABLED BIT(0) /* never disable this clock */ 16*c6ed4d73SDavid Lechner #define LPSC_SET_RATE_PARENT BIT(1) /* propagate set_rate to parent clock */ 17*c6ed4d73SDavid Lechner #define LPSC_FORCE BIT(2) /* requires MDCTL FORCE bit */ 18*c6ed4d73SDavid Lechner #define LPSC_LOCAL_RESET BIT(3) /* acts as reset provider */ 19*c6ed4d73SDavid Lechner 20*c6ed4d73SDavid Lechner struct davinci_lpsc_clkdev_info { 21*c6ed4d73SDavid Lechner const char *con_id; 22*c6ed4d73SDavid Lechner const char *dev_id; 23*c6ed4d73SDavid Lechner }; 24*c6ed4d73SDavid Lechner 25*c6ed4d73SDavid Lechner #define LPSC_CLKDEV(c, d) { \ 26*c6ed4d73SDavid Lechner .con_id = (c), \ 27*c6ed4d73SDavid Lechner .dev_id = (d) \ 28*c6ed4d73SDavid Lechner } 29*c6ed4d73SDavid Lechner 30*c6ed4d73SDavid Lechner #define LPSC_CLKDEV1(n, c, d) \ 31*c6ed4d73SDavid Lechner static const struct davinci_lpsc_clkdev_info n[] __initconst = { \ 32*c6ed4d73SDavid Lechner LPSC_CLKDEV((c), (d)), \ 33*c6ed4d73SDavid Lechner { } \ 34*c6ed4d73SDavid Lechner } 35*c6ed4d73SDavid Lechner 36*c6ed4d73SDavid Lechner #define LPSC_CLKDEV2(n, c1, d1, c2, d2) \ 37*c6ed4d73SDavid Lechner static const struct davinci_lpsc_clkdev_info n[] __initconst = { \ 38*c6ed4d73SDavid Lechner LPSC_CLKDEV((c1), (d1)), \ 39*c6ed4d73SDavid Lechner LPSC_CLKDEV((c2), (d2)), \ 40*c6ed4d73SDavid Lechner { } \ 41*c6ed4d73SDavid Lechner } 42*c6ed4d73SDavid Lechner 43*c6ed4d73SDavid Lechner #define LPSC_CLKDEV3(n, c1, d1, c2, d2, c3, d3) \ 44*c6ed4d73SDavid Lechner static const struct davinci_lpsc_clkdev_info n[] __initconst = { \ 45*c6ed4d73SDavid Lechner LPSC_CLKDEV((c1), (d1)), \ 46*c6ed4d73SDavid Lechner LPSC_CLKDEV((c2), (d2)), \ 47*c6ed4d73SDavid Lechner LPSC_CLKDEV((c3), (d3)), \ 48*c6ed4d73SDavid Lechner { } \ 49*c6ed4d73SDavid Lechner } 50*c6ed4d73SDavid Lechner 51*c6ed4d73SDavid Lechner /** 52*c6ed4d73SDavid Lechner * davinci_lpsc_clk_info - LPSC module-specific clock information 53*c6ed4d73SDavid Lechner * @name: the clock name 54*c6ed4d73SDavid Lechner * @parent: the parent clock name 55*c6ed4d73SDavid Lechner * @cdevs: optional array of clkdev lookup table info 56*c6ed4d73SDavid Lechner * @md: the local module domain (LPSC id) 57*c6ed4d73SDavid Lechner * @pd: the power domain id 58*c6ed4d73SDavid Lechner * @flags: bitmask of LPSC_* flags 59*c6ed4d73SDavid Lechner */ 60*c6ed4d73SDavid Lechner struct davinci_lpsc_clk_info { 61*c6ed4d73SDavid Lechner const char *name; 62*c6ed4d73SDavid Lechner const char *parent; 63*c6ed4d73SDavid Lechner const struct davinci_lpsc_clkdev_info *cdevs; 64*c6ed4d73SDavid Lechner u32 md; 65*c6ed4d73SDavid Lechner u32 pd; 66*c6ed4d73SDavid Lechner unsigned long flags; 67*c6ed4d73SDavid Lechner }; 68*c6ed4d73SDavid Lechner 69*c6ed4d73SDavid Lechner #define LPSC(m, d, n, p, c, f) \ 70*c6ed4d73SDavid Lechner { \ 71*c6ed4d73SDavid Lechner .name = #n, \ 72*c6ed4d73SDavid Lechner .parent = #p, \ 73*c6ed4d73SDavid Lechner .cdevs = (c), \ 74*c6ed4d73SDavid Lechner .md = (m), \ 75*c6ed4d73SDavid Lechner .pd = (d), \ 76*c6ed4d73SDavid Lechner .flags = (f), \ 77*c6ed4d73SDavid Lechner } 78*c6ed4d73SDavid Lechner 79*c6ed4d73SDavid Lechner int davinci_psc_register_clocks(struct device *dev, 80*c6ed4d73SDavid Lechner const struct davinci_lpsc_clk_info *info, 81*c6ed4d73SDavid Lechner u8 num_clks, 82*c6ed4d73SDavid Lechner void __iomem *base); 83*c6ed4d73SDavid Lechner 84*c6ed4d73SDavid Lechner int of_davinci_psc_clk_init(struct device *dev, 85*c6ed4d73SDavid Lechner const struct davinci_lpsc_clk_info *info, 86*c6ed4d73SDavid Lechner u8 num_clks, 87*c6ed4d73SDavid Lechner void __iomem *base); 88*c6ed4d73SDavid Lechner 89*c6ed4d73SDavid Lechner /* Device-specific data */ 90*c6ed4d73SDavid Lechner 91*c6ed4d73SDavid Lechner struct davinci_psc_init_data { 92*c6ed4d73SDavid Lechner struct clk_bulk_data *parent_clks; 93*c6ed4d73SDavid Lechner int num_parent_clks; 94*c6ed4d73SDavid Lechner int (*psc_init)(struct device *dev, void __iomem *base); 95*c6ed4d73SDavid Lechner }; 96*c6ed4d73SDavid Lechner 97*c6ed4d73SDavid Lechner #endif /* __CLK_DAVINCI_PSC_H__ */ 98