0197fa4beb31204c6a3730851333d31479d9fba2
[linux-3.10.git] / drivers / platform / tegra / tegra-bootrom-pmc-config.c
1 /*
2  * tegra-bootrom-pmc-config: Commands for bootrom to configure PMIC trhough PMC
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * Author: Laxman Dewangan <ldewangan@nvidia.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  */
17
18 #include <linux/err.h>
19 #include <linux/init.h>
20 #include <linux/of.h>
21 #include <linux/slab.h>
22 #include <linux/tegra-pmc.h>
23
24 #define PMC_REG_8bit_MASK                       0xFF
25 #define PMC_REG_16bit_MASK                      0xFFFF
26 #define PMC_BR_COMMAND_I2C_ADD_MASK             0x7F
27 #define PMC_BR_COMMAND_WR_COMMANDS_MASK         0x3F
28 #define PMC_BR_COMMAND_WR_COMMANDS_SHIFT        8
29 #define PMC_BR_COMMAND_OPERAND_SHIFT            15
30 #define PMC_BR_COMMAND_CSUM_MASK                0xFF
31 #define PMC_BR_COMMAND_CSUM_SHIFT               16
32 #define PMC_BR_COMMAND_PMUX_MASK                0x7
33 #define PMC_BR_COMMAND_PMUX_SHIFT               24
34 #define PMC_BR_COMMAND_CTRL_ID_MASK             0x7
35 #define PMC_BR_COMMAND_CTRL_ID_SHIFT            27
36 #define PMC_BR_COMMAND_CTRL_TYPE_SHIFT          30
37 #define PMC_BR_COMMAND_RST_EN_SHIFT             31
38
39 struct tegra_bootrom_block {
40         const char *name;
41         int address;
42         bool reg_8bits;
43         bool data_8bits;
44         bool i2c_controller;
45         int controller_id;
46         bool enable_reset;
47         int ncommands;
48         u32 *commands;
49 };
50
51 struct tegra_bootrom_commands {
52         u32 command_retry_count;
53         u32 delay_between_commands;
54         u32 wait_before_bus_clear;
55         struct tegra_bootrom_block *blocks;
56         int nblocks;
57 };
58
59 static int tegra_bootrom_get_commands_from_dt(struct device *dev,
60                 struct tegra_bootrom_commands **br_commands)
61 {
62         struct device_node *np = dev->of_node;
63         struct device_node *br_np, *child;
64         struct tegra_bootrom_commands *bcommands;
65         int *command_ptr;
66         struct tegra_bootrom_block *block;
67         int nblocks;
68         u32 reg, data, pval;
69         u32 *wr_commands;
70         int count, nblock, ncommands, i, reg_shift;
71         int ret;
72         int sz_bcommand, sz_blocks;
73
74         if (!np) {
75                 dev_err(dev, "No device node pointer\n");
76                 return -EINVAL;
77         }
78
79         br_np = of_find_node_by_name(np, "bootrom-commands");
80         if (!br_np) {
81                 dev_info(dev, "Bootrom commmands not found\n");
82                 return -ENOENT;
83         }
84
85         nblocks = of_get_child_count(br_np);
86         if (!nblocks) {
87                 dev_err(dev, "Bootrom I2C Command block not found\n");
88                 return -ENOENT;
89         }
90
91         count = 0;
92         for_each_child_of_node(br_np, child) {
93                 if (!of_device_is_available(child))
94                         continue;
95
96                 ret = of_property_count_u32(child, "nvidia,write-commands");
97                 if (ret < 0) {
98                         dev_err(dev, "Node %s does not have write-commnds\n",
99                                         child->full_name);
100                         return -EINVAL;
101                 }
102                 count += ret / 2;
103         }
104
105         sz_bcommand = (sizeof(*bcommands) + 0x3) & ~0x3;
106         sz_blocks = (sizeof(*block) + 0x3) & ~0x3;
107         bcommands = devm_kzalloc(dev,  sz_bcommand + nblocks * sz_blocks +
108                         count * sizeof(u32), GFP_KERNEL);
109         if (!bcommands)
110                 return -ENOMEM;
111
112         bcommands->nblocks = nblocks;
113         bcommands->blocks = (void *)bcommands + sz_bcommand;
114         command_ptr = (void *)bcommands->blocks + nblocks * sz_blocks;
115
116         of_property_read_u32(br_np, "nvidia,command-retries-count",
117                         &bcommands->command_retry_count);
118         of_property_read_u32(br_np, "nvidia,delay-between-commands-us",
119                         &bcommands->delay_between_commands);
120         of_property_read_u32(br_np, "nvidia,wait-before-start-bus-clear-us",
121                         &bcommands->wait_before_bus_clear);
122
123         nblock = 0;
124         for_each_child_of_node(br_np, child) {
125                 if (!of_device_is_available(child))
126                         continue;
127
128                 block = &bcommands->blocks[nblock];
129
130                 ret = of_property_read_u32(child, "reg", &pval);
131                 if (ret) {
132                         dev_err(dev, "Reg property missing on block %s\n",
133                                         child->name);
134                         return ret;
135                 }
136                 block->address = pval;
137                 of_property_read_string(child, "nvidia,command-names",
138                                 &block->name);
139                 block->reg_8bits = !of_property_read_bool(child,
140                                         "nvidia,enable-16bit-register");
141                 block->data_8bits = !of_property_read_bool(child,
142                                         "nvidia,enable-16bit-data");
143                 block->i2c_controller = of_property_read_bool(child,
144                                         "nvidia,controller-type-i2c");
145                 block->enable_reset = of_property_read_bool(child,
146                                         "nvidia,enable-controller-reset");
147                 count = of_property_count_u32(child, "nvidia,write-commands");
148                 ncommands = count / 2;
149
150                 block->commands = command_ptr;
151                 command_ptr += ncommands;
152                 wr_commands = block->commands;
153                 reg_shift = (block->data_8bits) ? 8 : 16;
154                 for (i = 0; i < ncommands; ++i) {
155                         of_property_read_u32_index(child,
156                                 "nvidia,write-commands", i * 2, &reg);
157                         of_property_read_u32_index(child,
158                                 "nvidia,write-commands", i * 2 + 1, &data);
159
160                         wr_commands[i] = (data << reg_shift) | reg;
161                 }
162                 block->ncommands = ncommands;
163                 nblock++;
164         }
165         *br_commands = bcommands;
166         return 0;
167 }
168
169 static int tegra210_configure_pmc_scratch(struct device *dev,
170                 struct tegra_bootrom_commands *br_commands)
171 {
172         struct tegra_bootrom_block *block;
173         int i, j, k;
174         u32 command;
175         int reg_offset = 1;
176         u32 reg_data_mask;
177         int command_pw;
178         u32 block_add, block_val, csum;
179
180         for (i = 0; i < br_commands->nblocks; ++i) {
181                 block = &br_commands->blocks[i];
182
183                 command = block->address & PMC_BR_COMMAND_I2C_ADD_MASK;
184                 command |= (block->ncommands <<
185                                         PMC_BR_COMMAND_WR_COMMANDS_SHIFT);
186                 if (!block->reg_8bits || !block->data_8bits)
187                         command |= BIT(PMC_BR_COMMAND_OPERAND_SHIFT);
188
189                 if (block->enable_reset)
190                         command |= BIT(PMC_BR_COMMAND_RST_EN_SHIFT);
191
192                 command |= (block->controller_id &
193                                 PMC_BR_COMMAND_CTRL_ID_MASK) <<
194                                         PMC_BR_COMMAND_CTRL_ID_SHIFT;
195
196                 /* Checksum will be added after parsing from reg/data */
197                 tegra_pmc_write_bootrom_command(reg_offset * 4, command);
198                 block_add = reg_offset * 4;
199                 block_val = command;
200                 reg_offset++;
201
202                 command_pw = (block->reg_8bits && block->data_8bits) ? 2 : 1;
203                 reg_data_mask = (command_pw == 1) ? 0xFFFF : 0xFFFFFFFFUL;
204                 csum = 0;
205
206                 for (j = 0; j < block->ncommands; j += command_pw) {
207                         command = block->commands[j] & reg_data_mask;
208                         if (command_pw == 2) {
209                                 j++;
210                                 if (j == block->ncommands)
211                                         goto reg_update;
212                         }
213
214                         command |= (block->commands[j] & reg_data_mask) << 16;
215 reg_update:
216                         tegra_pmc_write_bootrom_command(reg_offset * 4,
217                                                 command);
218                         for (k = 0; k < 4; ++k)
219                                 csum += (command >> (k * 8)) & 0xFF;
220                         reg_offset++;
221                 }
222                 for (k = 0; k < 4; ++k)
223                         csum += (block_val >> (k * 8)) & 0xFF;
224                 csum = 0x100 - csum;
225                 block_val = (block_val & 0xFF00FFFF) | ((csum & 0xFF) << 16);
226                 tegra_pmc_write_bootrom_command(block_add, block_val);
227         }
228
229         command = br_commands->command_retry_count & 0x7;
230         command |= (br_commands->delay_between_commands & 0x1F) << 3;
231         command |= (br_commands->nblocks & 0x7) << 8;
232         command |= (br_commands->wait_before_bus_clear & 0x1F) << 11;
233         tegra_pmc_write_bootrom_command(0, command);
234         return 0;
235 }
236
237 int tegra210_boorom_pmc_init(struct device *dev)
238 {
239         struct tegra_bootrom_commands *br_commands = NULL;
240         int ret;
241
242         ret = tegra_bootrom_get_commands_from_dt(dev, &br_commands);
243         if (ret < 0) {
244                 if (ret == -ENOENT)
245                         ret = 0;
246                 else
247                         pr_info("T210 pmc config for bootrom command failed\n");
248                 return ret;
249         }
250         ret = tegra210_configure_pmc_scratch(dev, br_commands);
251         if (ret < 0) {
252                 pr_info("T210 pmc config for bootrom command failed\n");
253                 return ret;
254         }
255         pr_info("T210 pmc config for bootrom command passed\n");
256         return 0;
257 }
258 EXPORT_SYMBOL(tegra210_boorom_pmc_init);