9 Replies Latest reply on Nov 12, 2019 1:55 AM by GernotH_31

    Registering the Map Driver in Linux for S70GL02GS.

    SrWu_4394436

      Dear All,

       

      We have interfaced NOR flash (part number :S70GL02GS) to processor is AM3352 via GPMC interface.

       

      In old kernel V3.20, physmap_flash_driver is also being registered using platform_driver_register() and hence physmap_flash_probe() is being called.  This is done as below:

       

      We have below MTD partiton table.  Member "name" platform_device is mapped to the "drivers/mtd/maps/physmap.c" structure.

       

      In board specific file they have below

      static struct physmap_flash_data norflash_data = {

      .width = 2,

      .parts = nor_partitions,

      .nr_parts = ARRAY_SIZE(nor_partitions),

      };

       

      static struct platform_device norflash = {

      .name = "physmap-flash",

      .id = 0,

      .dev = {

      .platform_data = &norflash_data,

      },

      .num_resources = 1,

      .resource = &norflash_resource,

      };

       

      static struct mtd_partition nor_partitions[] = {

      {

      .name = "uboot",

      .offset = 0,

      .size = 4 * SZ_128K,

      },

      }

       

      In "drivers/mtd/maps/physmap.c"

       

      static struct platform_device physmap_flash = {

              .name           = "physmap-flash",

              .id             = 0,

              .dev            = {

                      .platform_data  = &physmap_flash_data,

              },

              .num_resources  = 1,

              .resource       = &physmap_flash_resource,

      };

       

       

      How to achieve the same functionality in New Kernel Version 4.14 using DTS functionality? Or In DTS file, how this mapping to be done for S70GL02GS?

       

      I have tried below options:

       

      &gpmc {

                  compatible = "ti,am3352-gpmc";

                  ti,hwmods = "gpmc";

                  status = "okay";

       

       

                  nor@0,0 {

       

                          reg = <0 0x00000000 0x10000000>;

       

      linux,mtd-name = "physmap-flash.0";

      linux,mtd-name = "physmap-flash";

                  }

      }

       

      Till now your support has been great.  Thank you for that.  Please let me know if you have any input on this.

       

      Regards

      Srinivasa

        • 1. Re: Registering the Map Driver in Linux for S70GL02GS.
          GernotH_31

          Hi Srinivasa,

           

          the physmap driver needs a physical base address and memory window size. These parameters can be passed either via the device tree, or compiled directly into the driver. To compile it directly into the driver you can configure the parameters in the kernel configuration menu  (physmap section). That might be the easiest way.

           

          Of course, your board driver needs to set up the pads of the processor (SoC), clocks, ... appropriately for it to work.

           

          You probably will have to instrument the code (adding printk statements) and also attache a logic analyzer to further debug the situation.

           

          Best regards,

          Gernot

          • 2. Re: Registering the Map Driver in Linux for S70GL02GS.
            SrWu_4394436

            Hi Gernot,

             

            Our physmap driver is gpmc driver,  driver probe function "gpmc_probe()" is also being called.  This is our pysmap driver whcih is registered as below:

             

            static struct platform_driver gpmc_driver = {

                    .probe          = gpmc_probe,

                    .remove         = gpmc_remove,

                    .driver         = {

                            .name   = DEVICE_NAME,

                            .of_match_table = of_match_ptr(gpmc_dt_ids),

                            .pm     = &gpmc_pm_ops,

                    },

            };

             

            static __init int gpmc_init(void)

            {

                    printk("\n\n\nSrini debug @ line %d in function %s in file %s\n\n\n",__LINE__, __FUNCTION__, __FILE__);

                    return platform_driver_register(&gpmc_driver);

            }

             

             

            Here base address and memory window size is being allocated using gpmc_mem_init() function.  I am suspecting it is taking from bootloader because DTS file is being parsed after gpmc_mem_init().

             

            Next Suggestion

            Since my base address is 0x10000000 and flash size is 256 MB (0x10000000), I have tried below option,

            but it is ending up in Kernel panic.  Debugging on it...

            If you find any fault below, please let me know.

             

            Of course board driver has all ther parameters (like clock and other information set..).

             

            I have made sure that there are no errors in GPMC driver (using prink statments) and Kernel log is free of any errors.

            I have posted my queries on TI e2e forum

             

            https://e2e.ti.com/support/processors/f/791/p/834972/3122926#3122926

            AM3352: NOR flash issues in kernel - Processors forum - Processors - TI E2E support forums

             

             

            Regards

            Srinivasa

            • 3. Re: Registering the Map Driver in Linux for S70GL02GS.
              SrWu_4394436

              Hi Gernot,

               

              As per your input/suggestions, I have enabled below options in kernel configurations.  Now I am able to enter physmap_flash_probe() and below statement is printed.

               

              [    1.560353] physmap platform flash device: 10000000 at 10000000

               

              CONFIG_MTD_PHYSMAP_COMPAT=y

              CONFIG_MTD_PHYSMAP_START=0x10000000

              CONFIG_MTD_PHYSMAP_LEN=0x10000000

              CONFIG_MTD_PHYSMAP_BANKWIDTH=2

               

              However, I have kernel panic on this upon query to CFI chip. Please find the kernel logs attached.

               

              I understand it may not be related to flash issue, it has to do with Kernel.

               

              Please let me know if you have any suggestions on resoving kernel panic.

               

              Regards

              Srinivasa

              • 4. Re: Registering the Map Driver in Linux for S70GL02GS.
                GernotH_31

                Hi Srinivasa,

                 

                the kernel crashes in physmap_flash_probe() when it calls cfi_probe(). cfi_qry_presetn() checks for a (2nd?) device and this read access causes the situation. Probably that memory has not been correctly mapped.

                 

                You will have to add more debugging hints, print the arguments of the functions, e.g. for cfi_probe_chip(). Also check at what virtual address the physmap driver is mapping the flash to. Then understand the code and see what is wrong.

                 

                Best regards,

                Gernot

                • 5. Re: Registering the Map Driver in Linux for S70GL02GS.
                  SrWu_4394436

                  Hi Gernot,

                   

                  Just a clarification:

                  With 128 Mbytes flash (1 die) detected by Kernel, I should be able to erase/write/read on 128 MB flash without any dependency on second die.

                   

                  Is my understanding correct?

                   

                  Regards

                  Srinivasa

                  • 6. Re: Registering the Map Driver in Linux for S70GL02GS.
                    GernotH_31

                    Hi Srinivasa,

                     

                    yes, that is correct! If you have our S70GL02GS patch installed and if you provide only a 128 MB address window then the kernel will detect just 1 die and that should work fine.

                     

                    Best regards,

                    Gernot

                    • 7. Re: Registering the Map Driver in Linux for S70GL02GS.
                      SrWu_4394436

                      Hi Gernot,

                       

                      Thanks.  We are in touch with TI team.  Once I make progress will update on ths forum.

                       

                      Regards

                      Srinivasa

                      • 8. Re: Registering the Map Driver in Linux for S70GL02GS.
                        SrWu_4394436

                        Hi Gernot,

                         

                        We have made some progress on this.

                         

                        Problem statment:

                        We are able to detect only 1 die in the Linux version 4.14.79.

                        We are able to write only one sector.

                         

                         

                        We were debugging the CFI driver and control was reaching "cfi_probe_chip()" in "drivers/mtd/chips/cfi_probe.c".  In the below for loop,

                        We found that it was able to detect two chips upon disabled the alias check which is meant to be a safeguard against mis-configuration.

                         

                        TI team suggested to keep it *enabled* and asked us investigate the data structures and call sequences that happen during probe.

                         

                        Continuing further we noticed that disabling below function before alias check and having alias check enabled is making 2 chips detected!!!

                        I feel this should give us some hint.  Any input from will be great!!!

                         

                        // cfi_qry_mode_off(start, map, cfi);

                         

                         

                                /* Check each previous chip to see if it's an alias */

                                for (i=0; i < (base >> cfi->chipshift); i++) {

                                        unsigned long start;

                                        if(!test_bit(i, chip_map)) {

                                                /* Skip location; no valid chip at this address */

                                                continue;

                                        }

                                        start = i << cfi->chipshift;

                                        /* This chip should be in read mode if it's one

                                          we've already touched. */

                                        if (cfi_qry_present(map, start, cfi)) {

                                                /* Eep. This chip also had the QRY marker.

                                                * Is it an alias for the new one? */

                         

                         

                        /* Disabling this will make 2 chips detected */

                                                cfi_qry_mode_off(start, map, cfi); 

                         

                         

                        #if(1)

                                                /* If the QRY marker goes away, it's an alias */

                                                if (!cfi_qry_present(map, start, cfi)) {

                                                        xip_allowed(base, map);

                                                        printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",

                                                              map->name, base, start);

                         

                         

                                                        printk("%s: Found an alias at 0x%x for the chip at 0x%lx\n",

                                                              map->name, base, start);

                         

                         

                                printk("\n\n\nSrini debug @ line %d in function %s in file %s\n\n\n",__LINE__, __FUNCTION__, __FILE__);

                                                        return 0;

                                                }

                        #endif

                                                /* Yes, it's actually got QRY for data. Most

                                                * unfortunate. Stick the new chip in read mode

                                                * too and if it's the same, assume it's an alias. */

                                                /* FIXME: Use other modes to do a proper check */

                                                cfi_qry_mode_off(base, map, cfi);

                         

                         

                                                if (cfi_qry_present(map, base, cfi)) {

                                                        xip_allowed(base, map);

                                                        printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",

                                                              map->name, base, start);

                         

                         

                                                        printk("%s: Found an alias at 0x%x for the chip at 0x%lx\n",

                                                              map->name, base, start);

                         

                         

                                                        printk("\n\n\nSrini debug @ line %d in function %s in file %s\n\n\n",__LINE__, __FUNCTION__, __FILE__);

                                                        return 0;

                                                }

                                        }

                                }

                         

                         

                         

                         

                        We have posted the same on TI E2E forum.

                        http://e2e.ti.com/support/processors/f/791/p/834972/3129906#pi320966=5

                         

                        1. What is the purpose of cfi_qry_mode_off()?
                        2. Since same command is working in old kernel, I am suspecting some delay might be causing the issue.  Any comment on this?
                        3. Please reivew cfi_qry_mode_off() and give any inputs/hits

                         

                         

                        Regards

                        Srinivasa

                        1 of 1 people found this helpful
                        • 9. Re: Registering the Map Driver in Linux for S70GL02GS.
                          GernotH_31

                          Hi Srinivasa,

                           

                          cfi_qry_mode_on() enters CFI mode and cfi_qry_mode_off() exits CFI mode. The CFI signature is used to probe and detect devices.

                           

                          Detecting aliases does not help much, in this situation.

                           

                          Best regards,

                          Gernot