tegra-gmi.c (8449B)
1/* 2 * Driver for NVIDIA Generic Memory Interface 3 * 4 * Copyright (C) 2016 Host Mobility AB. All rights reserved. 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 11#include <linux/clk.h> 12#include <linux/delay.h> 13#include <linux/io.h> 14#include <linux/module.h> 15#include <linux/of_device.h> 16#include <linux/pm_runtime.h> 17#include <linux/reset.h> 18 19#include <soc/tegra/common.h> 20 21#define TEGRA_GMI_CONFIG 0x00 22#define TEGRA_GMI_CONFIG_GO BIT(31) 23#define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30) 24#define TEGRA_GMI_MUX_MODE BIT(28) 25#define TEGRA_GMI_RDY_BEFORE_DATA BIT(24) 26#define TEGRA_GMI_RDY_ACTIVE_HIGH BIT(23) 27#define TEGRA_GMI_ADV_ACTIVE_HIGH BIT(22) 28#define TEGRA_GMI_OE_ACTIVE_HIGH BIT(21) 29#define TEGRA_GMI_CS_ACTIVE_HIGH BIT(20) 30#define TEGRA_GMI_CS_SELECT(x) ((x & 0x7) << 4) 31 32#define TEGRA_GMI_TIMING0 0x10 33#define TEGRA_GMI_MUXED_WIDTH(x) ((x & 0xf) << 12) 34#define TEGRA_GMI_HOLD_WIDTH(x) ((x & 0xf) << 8) 35#define TEGRA_GMI_ADV_WIDTH(x) ((x & 0xf) << 4) 36#define TEGRA_GMI_CE_WIDTH(x) (x & 0xf) 37 38#define TEGRA_GMI_TIMING1 0x14 39#define TEGRA_GMI_WE_WIDTH(x) ((x & 0xff) << 16) 40#define TEGRA_GMI_OE_WIDTH(x) ((x & 0xff) << 8) 41#define TEGRA_GMI_WAIT_WIDTH(x) (x & 0xff) 42 43#define TEGRA_GMI_MAX_CHIP_SELECT 8 44 45struct tegra_gmi { 46 struct device *dev; 47 void __iomem *base; 48 struct clk *clk; 49 struct reset_control *rst; 50 51 u32 snor_config; 52 u32 snor_timing0; 53 u32 snor_timing1; 54}; 55 56static int tegra_gmi_enable(struct tegra_gmi *gmi) 57{ 58 int err; 59 60 pm_runtime_enable(gmi->dev); 61 err = pm_runtime_resume_and_get(gmi->dev); 62 if (err) { 63 pm_runtime_disable(gmi->dev); 64 return err; 65 } 66 67 reset_control_assert(gmi->rst); 68 usleep_range(2000, 4000); 69 reset_control_deassert(gmi->rst); 70 71 writel(gmi->snor_timing0, gmi->base + TEGRA_GMI_TIMING0); 72 writel(gmi->snor_timing1, gmi->base + TEGRA_GMI_TIMING1); 73 74 gmi->snor_config |= TEGRA_GMI_CONFIG_GO; 75 writel(gmi->snor_config, gmi->base + TEGRA_GMI_CONFIG); 76 77 return 0; 78} 79 80static void tegra_gmi_disable(struct tegra_gmi *gmi) 81{ 82 u32 config; 83 84 /* stop GMI operation */ 85 config = readl(gmi->base + TEGRA_GMI_CONFIG); 86 config &= ~TEGRA_GMI_CONFIG_GO; 87 writel(config, gmi->base + TEGRA_GMI_CONFIG); 88 89 reset_control_assert(gmi->rst); 90 91 pm_runtime_put_sync_suspend(gmi->dev); 92 pm_runtime_force_suspend(gmi->dev); 93} 94 95static int tegra_gmi_parse_dt(struct tegra_gmi *gmi) 96{ 97 struct device_node *child; 98 u32 property, ranges[4]; 99 int err; 100 101 child = of_get_next_available_child(gmi->dev->of_node, NULL); 102 if (!child) { 103 dev_err(gmi->dev, "no child nodes found\n"); 104 return -ENODEV; 105 } 106 107 /* 108 * We currently only support one child device due to lack of 109 * chip-select address decoding. Which means that we only have one 110 * chip-select line from the GMI controller. 111 */ 112 if (of_get_child_count(gmi->dev->of_node) > 1) 113 dev_warn(gmi->dev, "only one child device is supported."); 114 115 if (of_property_read_bool(child, "nvidia,snor-data-width-32bit")) 116 gmi->snor_config |= TEGRA_GMI_BUS_WIDTH_32BIT; 117 118 if (of_property_read_bool(child, "nvidia,snor-mux-mode")) 119 gmi->snor_config |= TEGRA_GMI_MUX_MODE; 120 121 if (of_property_read_bool(child, "nvidia,snor-rdy-active-before-data")) 122 gmi->snor_config |= TEGRA_GMI_RDY_BEFORE_DATA; 123 124 if (of_property_read_bool(child, "nvidia,snor-rdy-active-high")) 125 gmi->snor_config |= TEGRA_GMI_RDY_ACTIVE_HIGH; 126 127 if (of_property_read_bool(child, "nvidia,snor-adv-active-high")) 128 gmi->snor_config |= TEGRA_GMI_ADV_ACTIVE_HIGH; 129 130 if (of_property_read_bool(child, "nvidia,snor-oe-active-high")) 131 gmi->snor_config |= TEGRA_GMI_OE_ACTIVE_HIGH; 132 133 if (of_property_read_bool(child, "nvidia,snor-cs-active-high")) 134 gmi->snor_config |= TEGRA_GMI_CS_ACTIVE_HIGH; 135 136 /* Decode the CS# */ 137 err = of_property_read_u32_array(child, "ranges", ranges, 4); 138 if (err < 0) { 139 /* Invalid binding */ 140 if (err == -EOVERFLOW) { 141 dev_err(gmi->dev, 142 "failed to decode CS: invalid ranges length\n"); 143 goto error_cs; 144 } 145 146 /* 147 * If we reach here it means that the child node has an empty 148 * ranges or it does not exist at all. Attempt to decode the 149 * CS# from the reg property instead. 150 */ 151 err = of_property_read_u32(child, "reg", &property); 152 if (err < 0) { 153 dev_err(gmi->dev, 154 "failed to decode CS: no reg property found\n"); 155 goto error_cs; 156 } 157 } else { 158 property = ranges[1]; 159 } 160 161 /* Valid chip selects are CS0-CS7 */ 162 if (property >= TEGRA_GMI_MAX_CHIP_SELECT) { 163 dev_err(gmi->dev, "invalid chip select: %d", property); 164 err = -EINVAL; 165 goto error_cs; 166 } 167 168 gmi->snor_config |= TEGRA_GMI_CS_SELECT(property); 169 170 /* The default values that are provided below are reset values */ 171 if (!of_property_read_u32(child, "nvidia,snor-muxed-width", &property)) 172 gmi->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(property); 173 else 174 gmi->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(1); 175 176 if (!of_property_read_u32(child, "nvidia,snor-hold-width", &property)) 177 gmi->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(property); 178 else 179 gmi->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(1); 180 181 if (!of_property_read_u32(child, "nvidia,snor-adv-width", &property)) 182 gmi->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(property); 183 else 184 gmi->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(1); 185 186 if (!of_property_read_u32(child, "nvidia,snor-ce-width", &property)) 187 gmi->snor_timing0 |= TEGRA_GMI_CE_WIDTH(property); 188 else 189 gmi->snor_timing0 |= TEGRA_GMI_CE_WIDTH(4); 190 191 if (!of_property_read_u32(child, "nvidia,snor-we-width", &property)) 192 gmi->snor_timing1 |= TEGRA_GMI_WE_WIDTH(property); 193 else 194 gmi->snor_timing1 |= TEGRA_GMI_WE_WIDTH(1); 195 196 if (!of_property_read_u32(child, "nvidia,snor-oe-width", &property)) 197 gmi->snor_timing1 |= TEGRA_GMI_OE_WIDTH(property); 198 else 199 gmi->snor_timing1 |= TEGRA_GMI_OE_WIDTH(1); 200 201 if (!of_property_read_u32(child, "nvidia,snor-wait-width", &property)) 202 gmi->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(property); 203 else 204 gmi->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(3); 205 206error_cs: 207 of_node_put(child); 208 return err; 209} 210 211static int tegra_gmi_probe(struct platform_device *pdev) 212{ 213 struct device *dev = &pdev->dev; 214 struct tegra_gmi *gmi; 215 struct resource *res; 216 int err; 217 218 gmi = devm_kzalloc(dev, sizeof(*gmi), GFP_KERNEL); 219 if (!gmi) 220 return -ENOMEM; 221 222 platform_set_drvdata(pdev, gmi); 223 gmi->dev = dev; 224 225 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 226 gmi->base = devm_ioremap_resource(dev, res); 227 if (IS_ERR(gmi->base)) 228 return PTR_ERR(gmi->base); 229 230 gmi->clk = devm_clk_get(dev, "gmi"); 231 if (IS_ERR(gmi->clk)) { 232 dev_err(dev, "can not get clock\n"); 233 return PTR_ERR(gmi->clk); 234 } 235 236 gmi->rst = devm_reset_control_get(dev, "gmi"); 237 if (IS_ERR(gmi->rst)) { 238 dev_err(dev, "can not get reset\n"); 239 return PTR_ERR(gmi->rst); 240 } 241 242 err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); 243 if (err) 244 return err; 245 246 err = tegra_gmi_parse_dt(gmi); 247 if (err) 248 return err; 249 250 err = tegra_gmi_enable(gmi); 251 if (err < 0) 252 return err; 253 254 err = of_platform_default_populate(dev->of_node, NULL, dev); 255 if (err < 0) { 256 dev_err(dev, "fail to create devices.\n"); 257 tegra_gmi_disable(gmi); 258 return err; 259 } 260 261 return 0; 262} 263 264static int tegra_gmi_remove(struct platform_device *pdev) 265{ 266 struct tegra_gmi *gmi = platform_get_drvdata(pdev); 267 268 of_platform_depopulate(gmi->dev); 269 tegra_gmi_disable(gmi); 270 271 return 0; 272} 273 274static int __maybe_unused tegra_gmi_runtime_resume(struct device *dev) 275{ 276 struct tegra_gmi *gmi = dev_get_drvdata(dev); 277 int err; 278 279 err = clk_prepare_enable(gmi->clk); 280 if (err < 0) { 281 dev_err(gmi->dev, "failed to enable clock: %d\n", err); 282 return err; 283 } 284 285 return 0; 286} 287 288static int __maybe_unused tegra_gmi_runtime_suspend(struct device *dev) 289{ 290 struct tegra_gmi *gmi = dev_get_drvdata(dev); 291 292 clk_disable_unprepare(gmi->clk); 293 294 return 0; 295} 296 297static const struct dev_pm_ops tegra_gmi_pm = { 298 SET_RUNTIME_PM_OPS(tegra_gmi_runtime_suspend, tegra_gmi_runtime_resume, 299 NULL) 300}; 301 302static const struct of_device_id tegra_gmi_id_table[] = { 303 { .compatible = "nvidia,tegra20-gmi", }, 304 { .compatible = "nvidia,tegra30-gmi", }, 305 { } 306}; 307MODULE_DEVICE_TABLE(of, tegra_gmi_id_table); 308 309static struct platform_driver tegra_gmi_driver = { 310 .probe = tegra_gmi_probe, 311 .remove = tegra_gmi_remove, 312 .driver = { 313 .name = "tegra-gmi", 314 .of_match_table = tegra_gmi_id_table, 315 .pm = &tegra_gmi_pm, 316 }, 317}; 318module_platform_driver(tegra_gmi_driver); 319 320MODULE_AUTHOR("Mirza Krak <mirza.krak@gmail.com"); 321MODULE_DESCRIPTION("NVIDIA Tegra GMI Bus Driver"); 322MODULE_LICENSE("GPL v2");