linux/drivers/memory/ti-emif-pm.c
<<
>>
Prefs
   1/*
   2 * TI AM33XX SRAM EMIF Driver
   3 *
   4 * Copyright (C) 2016-2017 Texas Instruments Inc.
   5 *      Dave Gerlach
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License
   9 * version 2 as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/err.h>
  18#include <linux/genalloc.h>
  19#include <linux/io.h>
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/of.h>
  23#include <linux/of_platform.h>
  24#include <linux/platform_device.h>
  25#include <linux/sram.h>
  26#include <linux/ti-emif-sram.h>
  27
  28#include "emif.h"
  29
  30#define TI_EMIF_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
  31                                         (unsigned long)&ti_emif_sram)
  32
  33#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES           0x00a0
  34
  35struct ti_emif_data {
  36        phys_addr_t ti_emif_sram_phys;
  37        phys_addr_t ti_emif_sram_data_phys;
  38        unsigned long ti_emif_sram_virt;
  39        unsigned long ti_emif_sram_data_virt;
  40        struct gen_pool *sram_pool_code;
  41        struct gen_pool *sram_pool_data;
  42        struct ti_emif_pm_data pm_data;
  43        struct ti_emif_pm_functions pm_functions;
  44};
  45
  46static struct ti_emif_data *emif_instance;
  47
  48static u32 sram_suspend_address(struct ti_emif_data *emif_data,
  49                                unsigned long addr)
  50{
  51        return (emif_data->ti_emif_sram_virt +
  52                TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
  53}
  54
  55static phys_addr_t sram_resume_address(struct ti_emif_data *emif_data,
  56                                       unsigned long addr)
  57{
  58        return ((unsigned long)emif_data->ti_emif_sram_phys +
  59                TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
  60}
  61
  62static void ti_emif_free_sram(struct ti_emif_data *emif_data)
  63{
  64        gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
  65                      ti_emif_sram_sz);
  66        gen_pool_free(emif_data->sram_pool_data,
  67                      emif_data->ti_emif_sram_data_virt,
  68                      sizeof(struct emif_regs_amx3));
  69}
  70
  71static int ti_emif_alloc_sram(struct device *dev,
  72                              struct ti_emif_data *emif_data)
  73{
  74        struct device_node *np = dev->of_node;
  75        int ret;
  76
  77        emif_data->sram_pool_code = of_gen_pool_get(np, "sram", 0);
  78        if (!emif_data->sram_pool_code) {
  79                dev_err(dev, "Unable to get sram pool for ocmcram code\n");
  80                return -ENODEV;
  81        }
  82
  83        emif_data->ti_emif_sram_virt =
  84                        gen_pool_alloc(emif_data->sram_pool_code,
  85                                       ti_emif_sram_sz);
  86        if (!emif_data->ti_emif_sram_virt) {
  87                dev_err(dev, "Unable to allocate code memory from ocmcram\n");
  88                return -ENOMEM;
  89        }
  90
  91        /* Save physical address to calculate resume offset during pm init */
  92        emif_data->ti_emif_sram_phys =
  93                        gen_pool_virt_to_phys(emif_data->sram_pool_code,
  94                                              emif_data->ti_emif_sram_virt);
  95
  96        /* Get sram pool for data section and allocate space */
  97        emif_data->sram_pool_data = of_gen_pool_get(np, "sram", 1);
  98        if (!emif_data->sram_pool_data) {
  99                dev_err(dev, "Unable to get sram pool for ocmcram data\n");
 100                ret = -ENODEV;
 101                goto err_free_sram_code;
 102        }
 103
 104        emif_data->ti_emif_sram_data_virt =
 105                                gen_pool_alloc(emif_data->sram_pool_data,
 106                                               sizeof(struct emif_regs_amx3));
 107        if (!emif_data->ti_emif_sram_data_virt) {
 108                dev_err(dev, "Unable to allocate data memory from ocmcram\n");
 109                ret = -ENOMEM;
 110                goto err_free_sram_code;
 111        }
 112
 113        /* Save physical address to calculate resume offset during pm init */
 114        emif_data->ti_emif_sram_data_phys =
 115                gen_pool_virt_to_phys(emif_data->sram_pool_data,
 116                                      emif_data->ti_emif_sram_data_virt);
 117        /*
 118         * These functions are called during suspend path while MMU is
 119         * still on so add virtual base to offset for absolute address
 120         */
 121        emif_data->pm_functions.save_context =
 122                sram_suspend_address(emif_data,
 123                                     (unsigned long)ti_emif_save_context);
 124        emif_data->pm_functions.enter_sr =
 125                sram_suspend_address(emif_data,
 126                                     (unsigned long)ti_emif_enter_sr);
 127        emif_data->pm_functions.abort_sr =
 128                sram_suspend_address(emif_data,
 129                                     (unsigned long)ti_emif_abort_sr);
 130
 131        /*
 132         * These are called during resume path when MMU is not enabled
 133         * so physical address is used instead
 134         */
 135        emif_data->pm_functions.restore_context =
 136                sram_resume_address(emif_data,
 137                                    (unsigned long)ti_emif_restore_context);
 138        emif_data->pm_functions.exit_sr =
 139                sram_resume_address(emif_data,
 140                                    (unsigned long)ti_emif_exit_sr);
 141
 142        emif_data->pm_data.regs_virt =
 143                (struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt;
 144        emif_data->pm_data.regs_phys = emif_data->ti_emif_sram_data_phys;
 145
 146        return 0;
 147
 148err_free_sram_code:
 149        gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
 150                      ti_emif_sram_sz);
 151        return ret;
 152}
 153
 154static int ti_emif_push_sram(struct device *dev, struct ti_emif_data *emif_data)
 155{
 156        void *copy_addr;
 157        u32 data_addr;
 158
 159        copy_addr = sram_exec_copy(emif_data->sram_pool_code,
 160                                   (void *)emif_data->ti_emif_sram_virt,
 161                                   &ti_emif_sram, ti_emif_sram_sz);
 162        if (!copy_addr) {
 163                dev_err(dev, "Cannot copy emif code to sram\n");
 164                return -ENODEV;
 165        }
 166
 167        data_addr = sram_suspend_address(emif_data,
 168                                         (unsigned long)&ti_emif_pm_sram_data);
 169        copy_addr = sram_exec_copy(emif_data->sram_pool_code,
 170                                   (void *)data_addr,
 171                                   &emif_data->pm_data,
 172                                   sizeof(emif_data->pm_data));
 173        if (!copy_addr) {
 174                dev_err(dev, "Cannot copy emif data to code sram\n");
 175                return -ENODEV;
 176        }
 177
 178        return 0;
 179}
 180
 181/*
 182 * Due to Usage Note 3.1.2 "DDR3: JEDEC Compliance for Maximum
 183 * Self-Refresh Command Limit" found in AM335x Silicon Errata
 184 * (Document SPRZ360F Revised November 2013) we must configure
 185 * the self refresh delay timer to 0xA (8192 cycles) to avoid
 186 * generating too many refresh command from the EMIF.
 187 */
 188static void ti_emif_configure_sr_delay(struct ti_emif_data *emif_data)
 189{
 190        writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
 191               (emif_data->pm_data.ti_emif_base_addr_virt +
 192                EMIF_POWER_MANAGEMENT_CONTROL));
 193
 194        writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
 195               (emif_data->pm_data.ti_emif_base_addr_virt +
 196                EMIF_POWER_MANAGEMENT_CTRL_SHDW));
 197}
 198
 199/**
 200 * ti_emif_copy_pm_function_table - copy mapping of pm funcs in sram
 201 * @sram_pool: pointer to struct gen_pool where dst resides
 202 * @dst: void * to address that table should be copied
 203 *
 204 * Returns 0 if success other error code if table is not available
 205 */
 206int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst)
 207{
 208        void *copy_addr;
 209
 210        if (!emif_instance)
 211                return -ENODEV;
 212
 213        copy_addr = sram_exec_copy(sram_pool, dst,
 214                                   &emif_instance->pm_functions,
 215                                   sizeof(emif_instance->pm_functions));
 216        if (!copy_addr)
 217                return -ENODEV;
 218
 219        return 0;
 220}
 221EXPORT_SYMBOL_GPL(ti_emif_copy_pm_function_table);
 222
 223/**
 224 * ti_emif_get_mem_type - return type for memory type in use
 225 *
 226 * Returns memory type value read from EMIF or error code if fails
 227 */
 228int ti_emif_get_mem_type(void)
 229{
 230        unsigned long temp;
 231
 232        if (!emif_instance)
 233                return -ENODEV;
 234
 235        temp = readl(emif_instance->pm_data.ti_emif_base_addr_virt +
 236                     EMIF_SDRAM_CONFIG);
 237
 238        temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT;
 239        return temp;
 240}
 241EXPORT_SYMBOL_GPL(ti_emif_get_mem_type);
 242
 243static const struct of_device_id ti_emif_of_match[] = {
 244        { .compatible = "ti,emif-am3352", .data =
 245                                        (void *)EMIF_SRAM_AM33_REG_LAYOUT, },
 246        { .compatible = "ti,emif-am4372", .data =
 247                                        (void *)EMIF_SRAM_AM43_REG_LAYOUT, },
 248        {},
 249};
 250MODULE_DEVICE_TABLE(of, ti_emif_of_match);
 251
 252static int ti_emif_probe(struct platform_device *pdev)
 253{
 254        int ret;
 255        struct resource *res;
 256        struct device *dev = &pdev->dev;
 257        const struct of_device_id *match;
 258        struct ti_emif_data *emif_data;
 259
 260        emif_data = devm_kzalloc(dev, sizeof(*emif_data), GFP_KERNEL);
 261        if (!emif_data)
 262                return -ENOMEM;
 263
 264        match = of_match_device(ti_emif_of_match, &pdev->dev);
 265        if (!match)
 266                return -ENODEV;
 267
 268        emif_data->pm_data.ti_emif_sram_config = (unsigned long)match->data;
 269
 270        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 271        emif_data->pm_data.ti_emif_base_addr_virt = devm_ioremap_resource(dev,
 272                                                                          res);
 273        if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) {
 274                ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt);
 275                return ret;
 276        }
 277
 278        emif_data->pm_data.ti_emif_base_addr_phys = res->start;
 279
 280        ti_emif_configure_sr_delay(emif_data);
 281
 282        ret = ti_emif_alloc_sram(dev, emif_data);
 283        if (ret)
 284                return ret;
 285
 286        ret = ti_emif_push_sram(dev, emif_data);
 287        if (ret)
 288                goto fail_free_sram;
 289
 290        emif_instance = emif_data;
 291
 292        return 0;
 293
 294fail_free_sram:
 295        ti_emif_free_sram(emif_data);
 296
 297        return ret;
 298}
 299
 300static int ti_emif_remove(struct platform_device *pdev)
 301{
 302        struct ti_emif_data *emif_data = emif_instance;
 303
 304        emif_instance = NULL;
 305
 306        ti_emif_free_sram(emif_data);
 307
 308        return 0;
 309}
 310
 311static struct platform_driver ti_emif_driver = {
 312        .probe = ti_emif_probe,
 313        .remove = ti_emif_remove,
 314        .driver = {
 315                .name = KBUILD_MODNAME,
 316                .of_match_table = of_match_ptr(ti_emif_of_match),
 317        },
 318};
 319module_platform_driver(ti_emif_driver);
 320
 321MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
 322MODULE_DESCRIPTION("Texas Instruments SRAM EMIF driver");
 323MODULE_LICENSE("GPL v2");
 324