Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI AEMIF driver
0004  *
0005  * Copyright (C) 2010 - 2013 Texas Instruments Incorporated. http://www.ti.com/
0006  *
0007  * Authors:
0008  * Murali Karicheri <m-karicheri2@ti.com>
0009  * Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
0010  */
0011 
0012 #include <linux/clk.h>
0013 #include <linux/err.h>
0014 #include <linux/io.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/of_platform.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/platform_data/ti-aemif.h>
0021 
0022 #define TA_SHIFT    2
0023 #define RHOLD_SHIFT 4
0024 #define RSTROBE_SHIFT   7
0025 #define RSETUP_SHIFT    13
0026 #define WHOLD_SHIFT 17
0027 #define WSTROBE_SHIFT   20
0028 #define WSETUP_SHIFT    26
0029 #define EW_SHIFT    30
0030 #define SSTROBE_SHIFT   31
0031 
0032 #define TA(x)       ((x) << TA_SHIFT)
0033 #define RHOLD(x)    ((x) << RHOLD_SHIFT)
0034 #define RSTROBE(x)  ((x) << RSTROBE_SHIFT)
0035 #define RSETUP(x)   ((x) << RSETUP_SHIFT)
0036 #define WHOLD(x)    ((x) << WHOLD_SHIFT)
0037 #define WSTROBE(x)  ((x) << WSTROBE_SHIFT)
0038 #define WSETUP(x)   ((x) << WSETUP_SHIFT)
0039 #define EW(x)       ((x) << EW_SHIFT)
0040 #define SSTROBE(x)  ((x) << SSTROBE_SHIFT)
0041 
0042 #define ASIZE_MAX   0x1
0043 #define TA_MAX      0x3
0044 #define RHOLD_MAX   0x7
0045 #define RSTROBE_MAX 0x3f
0046 #define RSETUP_MAX  0xf
0047 #define WHOLD_MAX   0x7
0048 #define WSTROBE_MAX 0x3f
0049 #define WSETUP_MAX  0xf
0050 #define EW_MAX      0x1
0051 #define SSTROBE_MAX 0x1
0052 #define NUM_CS      4
0053 
0054 #define TA_VAL(x)   (((x) & TA(TA_MAX)) >> TA_SHIFT)
0055 #define RHOLD_VAL(x)    (((x) & RHOLD(RHOLD_MAX)) >> RHOLD_SHIFT)
0056 #define RSTROBE_VAL(x)  (((x) & RSTROBE(RSTROBE_MAX)) >> RSTROBE_SHIFT)
0057 #define RSETUP_VAL(x)   (((x) & RSETUP(RSETUP_MAX)) >> RSETUP_SHIFT)
0058 #define WHOLD_VAL(x)    (((x) & WHOLD(WHOLD_MAX)) >> WHOLD_SHIFT)
0059 #define WSTROBE_VAL(x)  (((x) & WSTROBE(WSTROBE_MAX)) >> WSTROBE_SHIFT)
0060 #define WSETUP_VAL(x)   (((x) & WSETUP(WSETUP_MAX)) >> WSETUP_SHIFT)
0061 #define EW_VAL(x)   (((x) & EW(EW_MAX)) >> EW_SHIFT)
0062 #define SSTROBE_VAL(x)  (((x) & SSTROBE(SSTROBE_MAX)) >> SSTROBE_SHIFT)
0063 
0064 #define NRCSR_OFFSET    0x00
0065 #define AWCCR_OFFSET    0x04
0066 #define A1CR_OFFSET 0x10
0067 
0068 #define ACR_ASIZE_MASK  0x3
0069 #define ACR_EW_MASK BIT(30)
0070 #define ACR_SSTROBE_MASK    BIT(31)
0071 #define ASIZE_16BIT 1
0072 
0073 #define CONFIG_MASK (TA(TA_MAX) | \
0074                 RHOLD(RHOLD_MAX) | \
0075                 RSTROBE(RSTROBE_MAX) |  \
0076                 RSETUP(RSETUP_MAX) | \
0077                 WHOLD(WHOLD_MAX) | \
0078                 WSTROBE(WSTROBE_MAX) | \
0079                 WSETUP(WSETUP_MAX) | \
0080                 EW(EW_MAX) | SSTROBE(SSTROBE_MAX) | \
0081                 ASIZE_MAX)
0082 
0083 /**
0084  * struct aemif_cs_data: structure to hold cs parameters
0085  * @cs: chip-select number
0086  * @wstrobe: write strobe width, ns
0087  * @rstrobe: read strobe width, ns
0088  * @wsetup: write setup width, ns
0089  * @whold: write hold width, ns
0090  * @rsetup: read setup width, ns
0091  * @rhold: read hold width, ns
0092  * @ta: minimum turn around time, ns
0093  * @enable_ss: enable/disable select strobe mode
0094  * @enable_ew: enable/disable extended wait mode
0095  * @asize: width of the asynchronous device's data bus
0096  */
0097 struct aemif_cs_data {
0098     u8  cs;
0099     u16 wstrobe;
0100     u16 rstrobe;
0101     u8  wsetup;
0102     u8  whold;
0103     u8  rsetup;
0104     u8  rhold;
0105     u8  ta;
0106     u8  enable_ss;
0107     u8  enable_ew;
0108     u8  asize;
0109 };
0110 
0111 /**
0112  * struct aemif_device: structure to hold device data
0113  * @base: base address of AEMIF registers
0114  * @clk: source clock
0115  * @clk_rate: clock's rate in kHz
0116  * @num_cs: number of assigned chip-selects
0117  * @cs_offset: start number of cs nodes
0118  * @cs_data: array of chip-select settings
0119  */
0120 struct aemif_device {
0121     void __iomem *base;
0122     struct clk *clk;
0123     unsigned long clk_rate;
0124     u8 num_cs;
0125     int cs_offset;
0126     struct aemif_cs_data cs_data[NUM_CS];
0127 };
0128 
0129 /**
0130  * aemif_calc_rate - calculate timing data.
0131  * @pdev: platform device to calculate for
0132  * @wanted: The cycle time needed in nanoseconds.
0133  * @clk: The input clock rate in kHz.
0134  * @max: The maximum divider value that can be programmed.
0135  *
0136  * On success, returns the calculated timing value minus 1 for easy
0137  * programming into AEMIF timing registers, else negative errno.
0138  */
0139 static int aemif_calc_rate(struct platform_device *pdev, int wanted,
0140                unsigned long clk, int max)
0141 {
0142     int result;
0143 
0144     result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
0145 
0146     dev_dbg(&pdev->dev, "%s: result %d from %ld, %d\n", __func__, result,
0147         clk, wanted);
0148 
0149     /* It is generally OK to have a more relaxed timing than requested... */
0150     if (result < 0)
0151         result = 0;
0152 
0153     /* ... But configuring tighter timings is not an option. */
0154     else if (result > max)
0155         result = -EINVAL;
0156 
0157     return result;
0158 }
0159 
0160 /**
0161  * aemif_config_abus - configure async bus parameters
0162  * @pdev: platform device to configure for
0163  * @csnum: aemif chip select number
0164  *
0165  * This function programs the given timing values (in real clock) into the
0166  * AEMIF registers taking the AEMIF clock into account.
0167  *
0168  * This function does not use any locking while programming the AEMIF
0169  * because it is expected that there is only one user of a given
0170  * chip-select.
0171  *
0172  * Returns 0 on success, else negative errno.
0173  */
0174 static int aemif_config_abus(struct platform_device *pdev, int csnum)
0175 {
0176     struct aemif_device *aemif = platform_get_drvdata(pdev);
0177     struct aemif_cs_data *data = &aemif->cs_data[csnum];
0178     int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
0179     unsigned long clk_rate = aemif->clk_rate;
0180     unsigned offset;
0181     u32 set, val;
0182 
0183     offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;
0184 
0185     ta  = aemif_calc_rate(pdev, data->ta, clk_rate, TA_MAX);
0186     rhold   = aemif_calc_rate(pdev, data->rhold, clk_rate, RHOLD_MAX);
0187     rstrobe = aemif_calc_rate(pdev, data->rstrobe, clk_rate, RSTROBE_MAX);
0188     rsetup  = aemif_calc_rate(pdev, data->rsetup, clk_rate, RSETUP_MAX);
0189     whold   = aemif_calc_rate(pdev, data->whold, clk_rate, WHOLD_MAX);
0190     wstrobe = aemif_calc_rate(pdev, data->wstrobe, clk_rate, WSTROBE_MAX);
0191     wsetup  = aemif_calc_rate(pdev, data->wsetup, clk_rate, WSETUP_MAX);
0192 
0193     if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
0194         whold < 0 || wstrobe < 0 || wsetup < 0) {
0195         dev_err(&pdev->dev, "%s: cannot get suitable timings\n",
0196             __func__);
0197         return -EINVAL;
0198     }
0199 
0200     set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
0201         WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
0202 
0203     set |= (data->asize & ACR_ASIZE_MASK);
0204     if (data->enable_ew)
0205         set |= ACR_EW_MASK;
0206     if (data->enable_ss)
0207         set |= ACR_SSTROBE_MASK;
0208 
0209     val = readl(aemif->base + offset);
0210     val &= ~CONFIG_MASK;
0211     val |= set;
0212     writel(val, aemif->base + offset);
0213 
0214     return 0;
0215 }
0216 
0217 static inline int aemif_cycles_to_nsec(int val, unsigned long clk_rate)
0218 {
0219     return ((val + 1) * NSEC_PER_MSEC) / clk_rate;
0220 }
0221 
0222 /**
0223  * aemif_get_hw_params - function to read hw register values
0224  * @pdev: platform device to read for
0225  * @csnum: aemif chip select number
0226  *
0227  * This function reads the defaults from the registers and update
0228  * the timing values. Required for get/set commands and also for
0229  * the case when driver needs to use defaults in hardware.
0230  */
0231 static void aemif_get_hw_params(struct platform_device *pdev, int csnum)
0232 {
0233     struct aemif_device *aemif = platform_get_drvdata(pdev);
0234     struct aemif_cs_data *data = &aemif->cs_data[csnum];
0235     unsigned long clk_rate = aemif->clk_rate;
0236     u32 val, offset;
0237 
0238     offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;
0239     val = readl(aemif->base + offset);
0240 
0241     data->ta = aemif_cycles_to_nsec(TA_VAL(val), clk_rate);
0242     data->rhold = aemif_cycles_to_nsec(RHOLD_VAL(val), clk_rate);
0243     data->rstrobe = aemif_cycles_to_nsec(RSTROBE_VAL(val), clk_rate);
0244     data->rsetup = aemif_cycles_to_nsec(RSETUP_VAL(val), clk_rate);
0245     data->whold = aemif_cycles_to_nsec(WHOLD_VAL(val), clk_rate);
0246     data->wstrobe = aemif_cycles_to_nsec(WSTROBE_VAL(val), clk_rate);
0247     data->wsetup = aemif_cycles_to_nsec(WSETUP_VAL(val), clk_rate);
0248     data->enable_ew = EW_VAL(val);
0249     data->enable_ss = SSTROBE_VAL(val);
0250     data->asize = val & ASIZE_MAX;
0251 }
0252 
0253 /**
0254  * of_aemif_parse_abus_config - parse CS configuration from DT
0255  * @pdev: platform device to parse for
0256  * @np: device node ptr
0257  *
0258  * This function update the emif async bus configuration based on the values
0259  * configured in a cs device binding node.
0260  */
0261 static int of_aemif_parse_abus_config(struct platform_device *pdev,
0262                       struct device_node *np)
0263 {
0264     struct aemif_device *aemif = platform_get_drvdata(pdev);
0265     struct aemif_cs_data *data;
0266     u32 cs;
0267     u32 val;
0268 
0269     if (of_property_read_u32(np, "ti,cs-chipselect", &cs)) {
0270         dev_dbg(&pdev->dev, "cs property is required");
0271         return -EINVAL;
0272     }
0273 
0274     if (cs - aemif->cs_offset >= NUM_CS || cs < aemif->cs_offset) {
0275         dev_dbg(&pdev->dev, "cs number is incorrect %d", cs);
0276         return -EINVAL;
0277     }
0278 
0279     if (aemif->num_cs >= NUM_CS) {
0280         dev_dbg(&pdev->dev, "cs count is more than %d", NUM_CS);
0281         return -EINVAL;
0282     }
0283 
0284     data = &aemif->cs_data[aemif->num_cs];
0285     data->cs = cs;
0286 
0287     /* read the current value in the hw register */
0288     aemif_get_hw_params(pdev, aemif->num_cs++);
0289 
0290     /* override the values from device node */
0291     if (!of_property_read_u32(np, "ti,cs-min-turnaround-ns", &val))
0292         data->ta = val;
0293 
0294     if (!of_property_read_u32(np, "ti,cs-read-hold-ns", &val))
0295         data->rhold = val;
0296 
0297     if (!of_property_read_u32(np, "ti,cs-read-strobe-ns", &val))
0298         data->rstrobe = val;
0299 
0300     if (!of_property_read_u32(np, "ti,cs-read-setup-ns", &val))
0301         data->rsetup = val;
0302 
0303     if (!of_property_read_u32(np, "ti,cs-write-hold-ns", &val))
0304         data->whold = val;
0305 
0306     if (!of_property_read_u32(np, "ti,cs-write-strobe-ns", &val))
0307         data->wstrobe = val;
0308 
0309     if (!of_property_read_u32(np, "ti,cs-write-setup-ns", &val))
0310         data->wsetup = val;
0311 
0312     if (!of_property_read_u32(np, "ti,cs-bus-width", &val))
0313         if (val == 16)
0314             data->asize = 1;
0315     data->enable_ew = of_property_read_bool(np, "ti,cs-extended-wait-mode");
0316     data->enable_ss = of_property_read_bool(np, "ti,cs-select-strobe-mode");
0317     return 0;
0318 }
0319 
0320 static const struct of_device_id aemif_of_match[] = {
0321     { .compatible = "ti,davinci-aemif", },
0322     { .compatible = "ti,da850-aemif", },
0323     {},
0324 };
0325 MODULE_DEVICE_TABLE(of, aemif_of_match);
0326 
0327 static int aemif_probe(struct platform_device *pdev)
0328 {
0329     int i;
0330     int ret = -ENODEV;
0331     struct device *dev = &pdev->dev;
0332     struct device_node *np = dev->of_node;
0333     struct device_node *child_np;
0334     struct aemif_device *aemif;
0335     struct aemif_platform_data *pdata;
0336     struct of_dev_auxdata *dev_lookup;
0337 
0338     aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL);
0339     if (!aemif)
0340         return -ENOMEM;
0341 
0342     pdata = dev_get_platdata(&pdev->dev);
0343     dev_lookup = pdata ? pdata->dev_lookup : NULL;
0344 
0345     platform_set_drvdata(pdev, aemif);
0346 
0347     aemif->clk = devm_clk_get(dev, NULL);
0348     if (IS_ERR(aemif->clk)) {
0349         dev_err(dev, "cannot get clock 'aemif'\n");
0350         return PTR_ERR(aemif->clk);
0351     }
0352 
0353     ret = clk_prepare_enable(aemif->clk);
0354     if (ret)
0355         return ret;
0356 
0357     aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC;
0358 
0359     if (np && of_device_is_compatible(np, "ti,da850-aemif"))
0360         aemif->cs_offset = 2;
0361     else if (pdata)
0362         aemif->cs_offset = pdata->cs_offset;
0363 
0364     aemif->base = devm_platform_ioremap_resource(pdev, 0);
0365     if (IS_ERR(aemif->base)) {
0366         ret = PTR_ERR(aemif->base);
0367         goto error;
0368     }
0369 
0370     if (np) {
0371         /*
0372          * For every controller device node, there is a cs device node
0373          * that describe the bus configuration parameters. This
0374          * functions iterate over these nodes and update the cs data
0375          * array.
0376          */
0377         for_each_available_child_of_node(np, child_np) {
0378             ret = of_aemif_parse_abus_config(pdev, child_np);
0379             if (ret < 0) {
0380                 of_node_put(child_np);
0381                 goto error;
0382             }
0383         }
0384     } else if (pdata && pdata->num_abus_data > 0) {
0385         for (i = 0; i < pdata->num_abus_data; i++, aemif->num_cs++) {
0386             aemif->cs_data[i].cs = pdata->abus_data[i].cs;
0387             aemif_get_hw_params(pdev, i);
0388         }
0389     }
0390 
0391     for (i = 0; i < aemif->num_cs; i++) {
0392         ret = aemif_config_abus(pdev, i);
0393         if (ret < 0) {
0394             dev_err(dev, "Error configuring chip select %d\n",
0395                 aemif->cs_data[i].cs);
0396             goto error;
0397         }
0398     }
0399 
0400     /*
0401      * Create a child devices explicitly from here to guarantee that the
0402      * child will be probed after the AEMIF timing parameters are set.
0403      */
0404     if (np) {
0405         for_each_available_child_of_node(np, child_np) {
0406             ret = of_platform_populate(child_np, NULL,
0407                            dev_lookup, dev);
0408             if (ret < 0) {
0409                 of_node_put(child_np);
0410                 goto error;
0411             }
0412         }
0413     } else if (pdata) {
0414         for (i = 0; i < pdata->num_sub_devices; i++) {
0415             pdata->sub_devices[i].dev.parent = dev;
0416             ret = platform_device_register(&pdata->sub_devices[i]);
0417             if (ret) {
0418                 dev_warn(dev, "Error register sub device %s\n",
0419                      pdata->sub_devices[i].name);
0420             }
0421         }
0422     }
0423 
0424     return 0;
0425 error:
0426     clk_disable_unprepare(aemif->clk);
0427     return ret;
0428 }
0429 
0430 static int aemif_remove(struct platform_device *pdev)
0431 {
0432     struct aemif_device *aemif = platform_get_drvdata(pdev);
0433 
0434     clk_disable_unprepare(aemif->clk);
0435     return 0;
0436 }
0437 
0438 static struct platform_driver aemif_driver = {
0439     .probe = aemif_probe,
0440     .remove = aemif_remove,
0441     .driver = {
0442         .name = "ti-aemif",
0443         .of_match_table = of_match_ptr(aemif_of_match),
0444     },
0445 };
0446 
0447 module_platform_driver(aemif_driver);
0448 
0449 MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
0450 MODULE_AUTHOR("Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>");
0451 MODULE_DESCRIPTION("Texas Instruments AEMIF driver");
0452 MODULE_LICENSE("GPL v2");
0453 MODULE_ALIAS("platform:" KBUILD_MODNAME);