Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI AM33XX SRAM EMIF Driver
0004  *
0005  * Copyright (C) 2016-2017 Texas Instruments Inc.
0006  *  Dave Gerlach
0007  */
0008 
0009 #include <linux/err.h>
0010 #include <linux/genalloc.h>
0011 #include <linux/io.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_platform.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/sram.h>
0018 #include <linux/ti-emif-sram.h>
0019 
0020 #include "emif.h"
0021 
0022 #define TI_EMIF_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
0023                      (unsigned long)&ti_emif_sram)
0024 
0025 #define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES       0x00a0
0026 
0027 struct ti_emif_data {
0028     phys_addr_t ti_emif_sram_phys;
0029     phys_addr_t ti_emif_sram_data_phys;
0030     unsigned long ti_emif_sram_virt;
0031     unsigned long ti_emif_sram_data_virt;
0032     struct gen_pool *sram_pool_code;
0033     struct gen_pool *sram_pool_data;
0034     struct ti_emif_pm_data pm_data;
0035     struct ti_emif_pm_functions pm_functions;
0036 };
0037 
0038 static struct ti_emif_data *emif_instance;
0039 
0040 static u32 sram_suspend_address(struct ti_emif_data *emif_data,
0041                 unsigned long addr)
0042 {
0043     return (emif_data->ti_emif_sram_virt +
0044         TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
0045 }
0046 
0047 static phys_addr_t sram_resume_address(struct ti_emif_data *emif_data,
0048                        unsigned long addr)
0049 {
0050     return ((unsigned long)emif_data->ti_emif_sram_phys +
0051         TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
0052 }
0053 
0054 static void ti_emif_free_sram(struct ti_emif_data *emif_data)
0055 {
0056     gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
0057               ti_emif_sram_sz);
0058     gen_pool_free(emif_data->sram_pool_data,
0059               emif_data->ti_emif_sram_data_virt,
0060               sizeof(struct emif_regs_amx3));
0061 }
0062 
0063 static int ti_emif_alloc_sram(struct device *dev,
0064                   struct ti_emif_data *emif_data)
0065 {
0066     struct device_node *np = dev->of_node;
0067     int ret;
0068 
0069     emif_data->sram_pool_code = of_gen_pool_get(np, "sram", 0);
0070     if (!emif_data->sram_pool_code) {
0071         dev_err(dev, "Unable to get sram pool for ocmcram code\n");
0072         return -ENODEV;
0073     }
0074 
0075     emif_data->ti_emif_sram_virt =
0076             gen_pool_alloc(emif_data->sram_pool_code,
0077                        ti_emif_sram_sz);
0078     if (!emif_data->ti_emif_sram_virt) {
0079         dev_err(dev, "Unable to allocate code memory from ocmcram\n");
0080         return -ENOMEM;
0081     }
0082 
0083     /* Save physical address to calculate resume offset during pm init */
0084     emif_data->ti_emif_sram_phys =
0085             gen_pool_virt_to_phys(emif_data->sram_pool_code,
0086                           emif_data->ti_emif_sram_virt);
0087 
0088     /* Get sram pool for data section and allocate space */
0089     emif_data->sram_pool_data = of_gen_pool_get(np, "sram", 1);
0090     if (!emif_data->sram_pool_data) {
0091         dev_err(dev, "Unable to get sram pool for ocmcram data\n");
0092         ret = -ENODEV;
0093         goto err_free_sram_code;
0094     }
0095 
0096     emif_data->ti_emif_sram_data_virt =
0097                 gen_pool_alloc(emif_data->sram_pool_data,
0098                            sizeof(struct emif_regs_amx3));
0099     if (!emif_data->ti_emif_sram_data_virt) {
0100         dev_err(dev, "Unable to allocate data memory from ocmcram\n");
0101         ret = -ENOMEM;
0102         goto err_free_sram_code;
0103     }
0104 
0105     /* Save physical address to calculate resume offset during pm init */
0106     emif_data->ti_emif_sram_data_phys =
0107         gen_pool_virt_to_phys(emif_data->sram_pool_data,
0108                       emif_data->ti_emif_sram_data_virt);
0109     /*
0110      * These functions are called during suspend path while MMU is
0111      * still on so add virtual base to offset for absolute address
0112      */
0113     emif_data->pm_functions.save_context =
0114         sram_suspend_address(emif_data,
0115                      (unsigned long)ti_emif_save_context);
0116     emif_data->pm_functions.enter_sr =
0117         sram_suspend_address(emif_data,
0118                      (unsigned long)ti_emif_enter_sr);
0119     emif_data->pm_functions.abort_sr =
0120         sram_suspend_address(emif_data,
0121                      (unsigned long)ti_emif_abort_sr);
0122 
0123     /*
0124      * These are called during resume path when MMU is not enabled
0125      * so physical address is used instead
0126      */
0127     emif_data->pm_functions.restore_context =
0128         sram_resume_address(emif_data,
0129                     (unsigned long)ti_emif_restore_context);
0130     emif_data->pm_functions.exit_sr =
0131         sram_resume_address(emif_data,
0132                     (unsigned long)ti_emif_exit_sr);
0133     emif_data->pm_functions.run_hw_leveling =
0134         sram_resume_address(emif_data,
0135                     (unsigned long)ti_emif_run_hw_leveling);
0136 
0137     emif_data->pm_data.regs_virt =
0138         (struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt;
0139     emif_data->pm_data.regs_phys = emif_data->ti_emif_sram_data_phys;
0140 
0141     return 0;
0142 
0143 err_free_sram_code:
0144     gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
0145               ti_emif_sram_sz);
0146     return ret;
0147 }
0148 
0149 static int ti_emif_push_sram(struct device *dev, struct ti_emif_data *emif_data)
0150 {
0151     void *copy_addr;
0152     u32 data_addr;
0153 
0154     copy_addr = sram_exec_copy(emif_data->sram_pool_code,
0155                    (void *)emif_data->ti_emif_sram_virt,
0156                    &ti_emif_sram, ti_emif_sram_sz);
0157     if (!copy_addr) {
0158         dev_err(dev, "Cannot copy emif code to sram\n");
0159         return -ENODEV;
0160     }
0161 
0162     data_addr = sram_suspend_address(emif_data,
0163                      (unsigned long)&ti_emif_pm_sram_data);
0164     copy_addr = sram_exec_copy(emif_data->sram_pool_code,
0165                    (void *)data_addr,
0166                    &emif_data->pm_data,
0167                    sizeof(emif_data->pm_data));
0168     if (!copy_addr) {
0169         dev_err(dev, "Cannot copy emif data to code sram\n");
0170         return -ENODEV;
0171     }
0172 
0173     return 0;
0174 }
0175 
0176 /*
0177  * Due to Usage Note 3.1.2 "DDR3: JEDEC Compliance for Maximum
0178  * Self-Refresh Command Limit" found in AM335x Silicon Errata
0179  * (Document SPRZ360F Revised November 2013) we must configure
0180  * the self refresh delay timer to 0xA (8192 cycles) to avoid
0181  * generating too many refresh command from the EMIF.
0182  */
0183 static void ti_emif_configure_sr_delay(struct ti_emif_data *emif_data)
0184 {
0185     writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
0186            (emif_data->pm_data.ti_emif_base_addr_virt +
0187         EMIF_POWER_MANAGEMENT_CONTROL));
0188 
0189     writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
0190            (emif_data->pm_data.ti_emif_base_addr_virt +
0191         EMIF_POWER_MANAGEMENT_CTRL_SHDW));
0192 }
0193 
0194 /**
0195  * ti_emif_copy_pm_function_table - copy mapping of pm funcs in sram
0196  * @sram_pool: pointer to struct gen_pool where dst resides
0197  * @dst: void * to address that table should be copied
0198  *
0199  * Returns 0 if success other error code if table is not available
0200  */
0201 int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst)
0202 {
0203     void *copy_addr;
0204 
0205     if (!emif_instance)
0206         return -ENODEV;
0207 
0208     copy_addr = sram_exec_copy(sram_pool, dst,
0209                    &emif_instance->pm_functions,
0210                    sizeof(emif_instance->pm_functions));
0211     if (!copy_addr)
0212         return -ENODEV;
0213 
0214     return 0;
0215 }
0216 EXPORT_SYMBOL_GPL(ti_emif_copy_pm_function_table);
0217 
0218 /**
0219  * ti_emif_get_mem_type - return type for memory type in use
0220  *
0221  * Returns memory type value read from EMIF or error code if fails
0222  */
0223 int ti_emif_get_mem_type(void)
0224 {
0225     unsigned long temp;
0226 
0227     if (!emif_instance)
0228         return -ENODEV;
0229 
0230     temp = readl(emif_instance->pm_data.ti_emif_base_addr_virt +
0231              EMIF_SDRAM_CONFIG);
0232 
0233     temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT;
0234     return temp;
0235 }
0236 EXPORT_SYMBOL_GPL(ti_emif_get_mem_type);
0237 
0238 static const struct of_device_id ti_emif_of_match[] = {
0239     { .compatible = "ti,emif-am3352", .data =
0240                     (void *)EMIF_SRAM_AM33_REG_LAYOUT, },
0241     { .compatible = "ti,emif-am4372", .data =
0242                     (void *)EMIF_SRAM_AM43_REG_LAYOUT, },
0243     {},
0244 };
0245 MODULE_DEVICE_TABLE(of, ti_emif_of_match);
0246 
0247 #ifdef CONFIG_PM_SLEEP
0248 static int ti_emif_resume(struct device *dev)
0249 {
0250     unsigned long tmp =
0251             __raw_readl((void __iomem *)emif_instance->ti_emif_sram_virt);
0252 
0253     /*
0254      * Check to see if what we are copying is already present in the
0255      * first byte at the destination, only copy if it is not which
0256      * indicates we have lost context and sram no longer contains
0257      * the PM code
0258      */
0259     if (tmp != ti_emif_sram)
0260         ti_emif_push_sram(dev, emif_instance);
0261 
0262     return 0;
0263 }
0264 
0265 static int ti_emif_suspend(struct device *dev)
0266 {
0267     /*
0268      * The contents will be present in DDR hence no need to
0269      * explicitly save
0270      */
0271     return 0;
0272 }
0273 #endif /* CONFIG_PM_SLEEP */
0274 
0275 static int ti_emif_probe(struct platform_device *pdev)
0276 {
0277     int ret;
0278     struct resource *res;
0279     struct device *dev = &pdev->dev;
0280     const struct of_device_id *match;
0281     struct ti_emif_data *emif_data;
0282 
0283     emif_data = devm_kzalloc(dev, sizeof(*emif_data), GFP_KERNEL);
0284     if (!emif_data)
0285         return -ENOMEM;
0286 
0287     match = of_match_device(ti_emif_of_match, &pdev->dev);
0288     if (!match)
0289         return -ENODEV;
0290 
0291     emif_data->pm_data.ti_emif_sram_config = (unsigned long)match->data;
0292 
0293     emif_data->pm_data.ti_emif_base_addr_virt = devm_platform_get_and_ioremap_resource(pdev,
0294                                                0,
0295                                                &res);
0296     if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) {
0297         ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt);
0298         return ret;
0299     }
0300 
0301     emif_data->pm_data.ti_emif_base_addr_phys = res->start;
0302 
0303     ti_emif_configure_sr_delay(emif_data);
0304 
0305     ret = ti_emif_alloc_sram(dev, emif_data);
0306     if (ret)
0307         return ret;
0308 
0309     ret = ti_emif_push_sram(dev, emif_data);
0310     if (ret)
0311         goto fail_free_sram;
0312 
0313     emif_instance = emif_data;
0314 
0315     return 0;
0316 
0317 fail_free_sram:
0318     ti_emif_free_sram(emif_data);
0319 
0320     return ret;
0321 }
0322 
0323 static int ti_emif_remove(struct platform_device *pdev)
0324 {
0325     struct ti_emif_data *emif_data = emif_instance;
0326 
0327     emif_instance = NULL;
0328 
0329     ti_emif_free_sram(emif_data);
0330 
0331     return 0;
0332 }
0333 
0334 static const struct dev_pm_ops ti_emif_pm_ops = {
0335     SET_SYSTEM_SLEEP_PM_OPS(ti_emif_suspend, ti_emif_resume)
0336 };
0337 
0338 static struct platform_driver ti_emif_driver = {
0339     .probe = ti_emif_probe,
0340     .remove = ti_emif_remove,
0341     .driver = {
0342         .name = KBUILD_MODNAME,
0343         .of_match_table = ti_emif_of_match,
0344         .pm = &ti_emif_pm_ops,
0345     },
0346 };
0347 module_platform_driver(ti_emif_driver);
0348 
0349 MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
0350 MODULE_DESCRIPTION("Texas Instruments SRAM EMIF driver");
0351 MODULE_LICENSE("GPL v2");