blob: 19864b5690e96f6911be5f9a9fc376cc0fa8e3df [file] [log] [blame]
Linus Walleij401301c2012-11-20 22:39:31 +01001/*
2 * Clock driver for the ARM Integrator/AP and Integrator/CP boards
3 * Copyright (C) 2012 Linus Walleij
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/clk-provider.h>
Linus Walleija6131632012-06-11 17:33:12 +020010#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/err.h>
Linus Walleij09c978b2014-01-10 15:57:27 +010013#include <linux/of.h>
14#include <linux/of_address.h>
Linus Walleija6131632012-06-11 17:33:12 +020015
16#include "clk-icst.h"
17
Linus Walleij09c978b2014-01-10 15:57:27 +010018#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
Linus Walleija6131632012-06-11 17:33:12 +020019
Linus Walleij09c978b2014-01-10 15:57:27 +010020/* Base offset for the core module */
21static void __iomem *cm_base;
22
23static const struct icst_params cp_auxosc_params = {
Linus Walleija6131632012-06-11 17:33:12 +020024 .ref = 24000000,
25 .vco_max = ICST525_VCO_MAX_5V,
26 .vco_min = ICST525_VCO_MIN,
27 .vd_min = 8,
28 .vd_max = 263,
29 .rd_min = 3,
30 .rd_max = 65,
31 .s2div = icst525_s2div,
32 .idx2s = icst525_idx2s,
33};
34
Linus Walleij09c978b2014-01-10 15:57:27 +010035static const struct clk_icst_desc __initdata cm_auxosc_desc = {
36 .params = &cp_auxosc_params,
Linus Walleij7a9ad672012-11-20 23:01:04 +010037 .vco_offset = 0x1c,
38 .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
Linus Walleija6131632012-06-11 17:33:12 +020039};
40
Linus Walleij09c978b2014-01-10 15:57:27 +010041static void __init of_integrator_cm_osc_setup(struct device_node *np)
Linus Walleija6131632012-06-11 17:33:12 +020042{
Linus Walleij09c978b2014-01-10 15:57:27 +010043 struct clk *clk = ERR_PTR(-EINVAL);
44 const char *clk_name = np->name;
45 const struct clk_icst_desc *desc = &cm_auxosc_desc;
Linus Walleija6131632012-06-11 17:33:12 +020046
Linus Walleij09c978b2014-01-10 15:57:27 +010047 if (!cm_base) {
48 /* Remap the core module base if not done yet */
49 struct device_node *parent;
Linus Walleija6131632012-06-11 17:33:12 +020050
Linus Walleij09c978b2014-01-10 15:57:27 +010051 parent = of_get_parent(np);
52 if (!np) {
53 pr_err("no parent on core module clock\n");
54 return;
55 }
56 cm_base = of_iomap(parent, 0);
57 if (!cm_base) {
58 pr_err("could not remap core module base\n");
59 return;
60 }
61 }
Linus Walleija6131632012-06-11 17:33:12 +020062
Linus Walleij09c978b2014-01-10 15:57:27 +010063 clk = icst_clk_register(NULL, desc, clk_name, cm_base);
64 if (!IS_ERR(clk))
65 of_clk_add_provider(np, of_clk_src_simple_get, clk);
Linus Walleija6131632012-06-11 17:33:12 +020066}
Linus Walleij09c978b2014-01-10 15:57:27 +010067CLK_OF_DECLARE(integrator_cm_auxosc_clk,
68 "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);