Blame view

drivers/clk/versatile/clk-impd1.c 4.99 KB
70ee65771   Linus Walleij   clk: move IM-PD1 ...
1
2
  /*
   * Clock driver for the ARM Integrator/IM-PD1 board
8e048b999   Linus Walleij   clk: versatile: f...
3
   * Copyright (C) 2012-2013 Linus Walleij
70ee65771   Linus Walleij   clk: move IM-PD1 ...
4
5
6
7
8
9
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  #include <linux/clk-provider.h>
70ee65771   Linus Walleij   clk: move IM-PD1 ...
10
11
12
13
  #include <linux/clkdev.h>
  #include <linux/err.h>
  #include <linux/io.h>
  #include <linux/platform_data/clk-integrator.h>
70ee65771   Linus Walleij   clk: move IM-PD1 ...
14
  #include "clk-icst.h"
cc0cc4ca0   Linus Walleij   ARM: integrator: ...
15
16
17
  #define IMPD1_OSC1	0x00
  #define IMPD1_OSC2	0x04
  #define IMPD1_LOCK	0x08
70ee65771   Linus Walleij   clk: move IM-PD1 ...
18
  struct impd1_clk {
222cb1bf1   Linus Walleij   clk: impd1: add p...
19
20
  	char *pclkname;
  	struct clk *pclk;
8e048b999   Linus Walleij   clk: versatile: f...
21
22
23
24
25
26
  	char *vco1name;
  	struct clk *vco1clk;
  	char *vco2name;
  	struct clk *vco2clk;
  	struct clk *mmciclk;
  	char *uartname;
70ee65771   Linus Walleij   clk: move IM-PD1 ...
27
  	struct clk *uartclk;
8e048b999   Linus Walleij   clk: versatile: f...
28
29
30
31
  	char *spiname;
  	struct clk *spiclk;
  	char *scname;
  	struct clk *scclk;
222cb1bf1   Linus Walleij   clk: impd1: add p...
32
  	struct clk_lookup *clks[15];
70ee65771   Linus Walleij   clk: move IM-PD1 ...
33
  };
8e048b999   Linus Walleij   clk: versatile: f...
34
  /* One entry for each connected IM-PD1 LM */
70ee65771   Linus Walleij   clk: move IM-PD1 ...
35
36
37
  static struct impd1_clk impd1_clks[4];
  
  /*
8e048b999   Linus Walleij   clk: versatile: f...
38
   * There are two VCO's on the IM-PD1
70ee65771   Linus Walleij   clk: move IM-PD1 ...
39
   */
8e048b999   Linus Walleij   clk: versatile: f...
40
  static const struct icst_params impd1_vco1_params = {
70ee65771   Linus Walleij   clk: move IM-PD1 ...
41
42
43
44
45
46
47
48
49
50
51
52
  	.ref		= 24000000,	/* 24 MHz */
  	.vco_max	= ICST525_VCO_MAX_3V,
  	.vco_min	= ICST525_VCO_MIN,
  	.vd_min		= 12,
  	.vd_max		= 519,
  	.rd_min		= 3,
  	.rd_max		= 120,
  	.s2div		= icst525_s2div,
  	.idx2s		= icst525_idx2s,
  };
  
  static const struct clk_icst_desc impd1_icst1_desc = {
8e048b999   Linus Walleij   clk: versatile: f...
53
  	.params = &impd1_vco1_params,
70ee65771   Linus Walleij   clk: move IM-PD1 ...
54
55
56
  	.vco_offset = IMPD1_OSC1,
  	.lock_offset = IMPD1_LOCK,
  };
8e048b999   Linus Walleij   clk: versatile: f...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  static const struct icst_params impd1_vco2_params = {
  	.ref		= 24000000,	/* 24 MHz */
  	.vco_max	= ICST525_VCO_MAX_3V,
  	.vco_min	= ICST525_VCO_MIN,
  	.vd_min		= 12,
  	.vd_max		= 519,
  	.rd_min		= 3,
  	.rd_max		= 120,
  	.s2div		= icst525_s2div,
  	.idx2s		= icst525_idx2s,
  };
  
  static const struct clk_icst_desc impd1_icst2_desc = {
  	.params = &impd1_vco2_params,
  	.vco_offset = IMPD1_OSC2,
  	.lock_offset = IMPD1_LOCK,
  };
70ee65771   Linus Walleij   clk: move IM-PD1 ...
74
75
76
77
78
79
80
81
82
  /**
   * integrator_impd1_clk_init() - set up the integrator clock tree
   * @base: base address of the logic module (LM)
   * @id: the ID of this LM
   */
  void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
  {
  	struct impd1_clk *imc;
  	struct clk *clk;
222cb1bf1   Linus Walleij   clk: impd1: add p...
83
  	struct clk *pclk;
70ee65771   Linus Walleij   clk: move IM-PD1 ...
84
85
86
87
88
89
90
91
  	int i;
  
  	if (id > 3) {
  		pr_crit("no more than 4 LMs can be attached
  ");
  		return;
  	}
  	imc = &impd1_clks[id];
222cb1bf1   Linus Walleij   clk: impd1: add p...
92
93
  	/* Register the fixed rate PCLK */
  	imc->pclkname = kasprintf(GFP_KERNEL, "lm%x-pclk", id);
ac82a8b50   Stephen Boyd   clk: versatile: R...
94
  	pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, 0, 0);
222cb1bf1   Linus Walleij   clk: impd1: add p...
95
  	imc->pclk = pclk;
8e048b999   Linus Walleij   clk: versatile: f...
96
  	imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
bf6edb4bb   Linus Walleij   clk: versatile: p...
97
98
  	clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL,
  				base);
ae6e694ef   Linus Walleij   clk: versatile: p...
99
  	imc->vco1clk = clk;
222cb1bf1   Linus Walleij   clk: impd1: add p...
100
101
  	imc->clks[0] = clkdev_alloc(pclk, "apb_pclk", "lm%x:01000", id);
  	imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
102

8e048b999   Linus Walleij   clk: versatile: f...
103
104
  	/* VCO2 is also called "CLK2" */
  	imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
bf6edb4bb   Linus Walleij   clk: versatile: p...
105
106
  	clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL,
  				base);
8e048b999   Linus Walleij   clk: versatile: f...
107
108
109
  	imc->vco2clk = clk;
  
  	/* MMCI uses CLK2 right off */
222cb1bf1   Linus Walleij   clk: impd1: add p...
110
111
  	imc->clks[2] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00700", id);
  	imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00700", id);
8e048b999   Linus Walleij   clk: versatile: f...
112
113
114
115
116
  
  	/* UART reference clock divides CLK2 by a fixed factor 4 */
  	imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id);
  	clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name,
  				   CLK_IGNORE_UNUSED, 1, 4);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
117
  	imc->uartclk = clk;
222cb1bf1   Linus Walleij   clk: impd1: add p...
118
119
120
121
  	imc->clks[4] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00100", id);
  	imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
  	imc->clks[6] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00200", id);
  	imc->clks[7] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
8e048b999   Linus Walleij   clk: versatile: f...
122
123
124
125
126
  
  	/* SPI PL022 clock divides CLK2 by a fixed factor 64 */
  	imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id);
  	clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name,
  				   CLK_IGNORE_UNUSED, 1, 64);
222cb1bf1   Linus Walleij   clk: impd1: add p...
127
128
129
130
131
132
133
  	imc->clks[8] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00300", id);
  	imc->clks[9] = clkdev_alloc(clk, NULL, "lm%x:00300", id);
  
  	/* The GPIO blocks and AACI have only PCLK */
  	imc->clks[10] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00400", id);
  	imc->clks[11] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00500", id);
  	imc->clks[12] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00800", id);
8e048b999   Linus Walleij   clk: versatile: f...
134
135
136
137
138
139
  
  	/* Smart Card clock divides CLK2 by a fixed factor 4 */
  	imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id);
  	clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name,
  				   CLK_IGNORE_UNUSED, 1, 4);
  	imc->scclk = clk;
222cb1bf1   Linus Walleij   clk: impd1: add p...
140
141
  	imc->clks[13] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00600", id);
  	imc->clks[14] = clkdev_alloc(clk, NULL, "lm%x:00600", id);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
142
143
144
145
  
  	for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
  		clkdev_add(imc->clks[i]);
  }
a218d7fa3   Arnd Bergmann   clk/versatile: ex...
146
  EXPORT_SYMBOL_GPL(integrator_impd1_clk_init);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
147
148
149
150
151
152
153
154
155
156
157
158
  
  void integrator_impd1_clk_exit(unsigned int id)
  {
  	int i;
  	struct impd1_clk *imc;
  
  	if (id > 3)
  		return;
  	imc = &impd1_clks[id];
  
  	for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
  		clkdev_drop(imc->clks[i]);
8e048b999   Linus Walleij   clk: versatile: f...
159
  	clk_unregister(imc->spiclk);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
160
  	clk_unregister(imc->uartclk);
8e048b999   Linus Walleij   clk: versatile: f...
161
162
  	clk_unregister(imc->vco2clk);
  	clk_unregister(imc->vco1clk);
222cb1bf1   Linus Walleij   clk: impd1: add p...
163
  	clk_unregister(imc->pclk);
8e048b999   Linus Walleij   clk: versatile: f...
164
165
166
167
168
  	kfree(imc->scname);
  	kfree(imc->spiname);
  	kfree(imc->uartname);
  	kfree(imc->vco2name);
  	kfree(imc->vco1name);
222cb1bf1   Linus Walleij   clk: impd1: add p...
169
  	kfree(imc->pclkname);
70ee65771   Linus Walleij   clk: move IM-PD1 ...
170
  }
a218d7fa3   Arnd Bergmann   clk/versatile: ex...
171
  EXPORT_SYMBOL_GPL(integrator_impd1_clk_exit);