[4/5] soc: qcom: Add LLCC support for multi channel DDR

Message ID 20230313071325.21605-5-quic_kbajaj@quicinc.com
State New
Headers
Series soc: qcom: llcc: Add support for QDU1000/QRU1000 |

Commit Message

Komal Bajaj March 13, 2023, 7:13 a.m. UTC
  Add LLCC support for multi channel DDR configurations
based off of a feature register.

Signed-off-by: Komal Bajaj <quic_kbajaj@quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c       | 56 ++++++++++++++++++++++++++++--
 include/linux/soc/qcom/llcc-qcom.h |  2 ++
 2 files changed, 55 insertions(+), 3 deletions(-)
  

Comments

kernel test robot March 13, 2023, 9:44 a.m. UTC | #1
Hi Komal,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.3-rc2 next-20230310]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Komal-Bajaj/soc-qcom-llcc-Refactor-llcc-driver-to-support-multiple-configuration/20230313-151543
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20230313071325.21605-5-quic_kbajaj%40quicinc.com
patch subject: [PATCH 4/5] soc: qcom: Add LLCC support for multi channel DDR
config: arc-randconfig-r043-20230313 (https://download.01.org/0day-ci/archive/20230313/202303131704.RIYLnDCZ-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ef96faadeb37bb94f77361aef72e2d863fe6e0f9
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Komal-Bajaj/soc-qcom-llcc-Refactor-llcc-driver-to-support-multiple-configuration/20230313-151543
        git checkout ef96faadeb37bb94f77361aef72e2d863fe6e0f9
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash drivers/soc/qcom/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303131704.RIYLnDCZ-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/soc/qcom/llcc-qcom.c:20:10: fatal error: linux/qcom_scm.h: No such file or directory
      20 | #include <linux/qcom_scm.h>
         |          ^~~~~~~~~~~~~~~~~~
   compilation terminated.


vim +20 drivers/soc/qcom/llcc-qcom.c

  > 20	#include <linux/qcom_scm.h>
    21	#include <linux/soc/qcom/llcc-qcom.h>
    22
  
kernel test robot March 13, 2023, 9:54 a.m. UTC | #2
Hi Komal,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.3-rc2 next-20230310]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Komal-Bajaj/soc-qcom-llcc-Refactor-llcc-driver-to-support-multiple-configuration/20230313-151543
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20230313071325.21605-5-quic_kbajaj%40quicinc.com
patch subject: [PATCH 4/5] soc: qcom: Add LLCC support for multi channel DDR
config: hexagon-randconfig-r041-20230312 (https://download.01.org/0day-ci/archive/20230313/202303131722.uo5Li701-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project 67409911353323ca5edf2049ef0df54132fa1ca7)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ef96faadeb37bb94f77361aef72e2d863fe6e0f9
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Komal-Bajaj/soc-qcom-llcc-Refactor-llcc-driver-to-support-multiple-configuration/20230313-151543
        git checkout ef96faadeb37bb94f77361aef72e2d863fe6e0f9
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/soc/qcom/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303131722.uo5Li701-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/soc/qcom/llcc-qcom.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/soc/qcom/llcc-qcom.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/soc/qcom/llcc-qcom.c:11:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
>> drivers/soc/qcom/llcc-qcom.c:20:10: fatal error: 'linux/qcom_scm.h' file not found
   #include <linux/qcom_scm.h>
            ^~~~~~~~~~~~~~~~~~
   6 warnings and 1 error generated.


vim +20 drivers/soc/qcom/llcc-qcom.c

  > 20	#include <linux/qcom_scm.h>
    21	#include <linux/soc/qcom/llcc-qcom.h>
    22
  
Konrad Dybcio March 13, 2023, 10:01 a.m. UTC | #3
[...]
>    include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
>                                                          ~~~~~~~~~~ ^
>    include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
>                                                          ~~~~~~~~~~ ^
>>> drivers/soc/qcom/llcc-qcom.c:20:10: fatal error: 'linux/qcom_scm.h' file not found
>    #include <linux/qcom_scm.h>
This moved over a month ago. Please send patches against fresh -next
and not some ancient tree.

Konrad
>             ^~~~~~~~~~~~~~~~~~
>    6 warnings and 1 error generated.
> 
> 
> vim +20 drivers/soc/qcom/llcc-qcom.c
> 
>   > 20	#include <linux/qcom_scm.h>
>     21	#include <linux/soc/qcom/llcc-qcom.h>
>     22	
>
  
Komal Bajaj March 13, 2023, 1:01 p.m. UTC | #4
On 3/13/2023 3:31 PM, Konrad Dybcio wrote:
> [...]
>>     include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>>             __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
>>                                                           ~~~~~~~~~~ ^
>>     include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>>             __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
>>                                                           ~~~~~~~~~~ ^
>>>> drivers/soc/qcom/llcc-qcom.c:20:10: fatal error: 'linux/qcom_scm.h' file not found
>>     #include <linux/qcom_scm.h>
> This moved over a month ago. Please send patches against fresh -next
> and not some ancient tree.
>
> Konrad

Thanks for reviewing it, will send next patch series against fresh -next 
tree.

Thanks
Komal

>>              ^~~~~~~~~~~~~~~~~~
>>     6 warnings and 1 error generated.
>>
>>
>> vim +20 drivers/soc/qcom/llcc-qcom.c
>>
>>    > 20	#include <linux/qcom_scm.h>
>>      21	#include <linux/soc/qcom/llcc-qcom.h>
>>      22	
>>
  

Patch

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 00699a0c047e..696f1f46dd61 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -17,6 +17,7 @@ 
 #include <linux/regmap.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
+#include <linux/qcom_scm.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
 #define ACTIVATE                      BIT(0)
@@ -924,6 +925,40 @@  static int qcom_llcc_cfg_program(struct platform_device *pdev,
 	return ret;
 }
 
+static int qcom_llcc_get_cfg_index(struct platform_device *pdev, u32 *cfg_index)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *ch_res = NULL;
+
+	u32 ch_reg_sz;
+	u32 ch_reg_off;
+	u32 val;
+	int ret = 0;
+
+	ch_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "multi_channel_register");
+	if (ch_res) {
+		if (of_property_read_u32(dev->of_node, "multi-ch-bit-off", &ch_reg_off)) {
+			dev_err(&pdev->dev,
+				"Couldn't get offset for multi channel feature register\n");
+			return -ENODEV;
+		}
+		if (of_property_read_u32_index(dev->of_node, "multi-ch-bit-off", 1, &ch_reg_sz)) {
+			dev_err(&pdev->dev,
+				"Couldn't get size of multi channel feature register\n");
+			return -ENODEV;
+		}
+
+		if (qcom_scm_io_readl(ch_res->start, &val)) {
+			dev_err(&pdev->dev, "Couldn't access multi channel feature register\n");
+			ret = -EINVAL;
+		}
+		*cfg_index = (val >> ch_reg_off) & ((1 << ch_reg_sz) - 1);
+	} else
+		*cfg_index = 0;
+
+	return ret;
+}
+
 static int qcom_llcc_remove(struct platform_device *pdev)
 {
 	/* Set the global pointer to a error code to avoid referencing it */
@@ -956,10 +991,13 @@  static int qcom_llcc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int ret, i;
 	struct platform_device *llcc_edac;
-	const struct qcom_llcc_config *cfg;
+	const struct qcom_llcc_config *cfg, *entry;
 	const struct llcc_slice_config *llcc_cfg;
+
 	u32 sz;
+	u32 cfg_index;
 	u32 version;
+	u32 no_of_entries = 0;
 
 	drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
 	if (!drv_data) {
@@ -999,8 +1037,20 @@  static int qcom_llcc_probe(struct platform_device *pdev)
 	num_banks >>= LLCC_LB_CNT_SHIFT;
 	drv_data->num_banks = num_banks;
 
-	llcc_cfg = cfg[0].sct_data;
-	sz = cfg[0].size;
+	ret = qcom_llcc_get_cfg_index(pdev, &cfg_index);
+	if (ret)
+		goto err;
+
+	for (entry = cfg; entry->sct_data; entry++, no_of_entries++)
+		;
+	if (cfg_index >= no_of_entries) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	drv_data->cfg_index = cfg_index;
+	llcc_cfg = cfg[cfg_index].sct_data;
+	sz = cfg[cfg_index].size;
 
 	for (i = 0; i < sz; i++)
 		if (llcc_cfg[i].slice_id > drv_data->max_slices)
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index ad1fd718169d..225891a02f5d 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -125,6 +125,7 @@  struct llcc_edac_reg_offset {
  * @cfg: pointer to the data structure for slice configuration
  * @edac_reg_offset: Offset of the LLCC EDAC registers
  * @lock: mutex associated with each slice
+ * @cfg_index: index of config table if multiple configs present for a target
  * @cfg_size: size of the config data table
  * @max_slices: max slices as read from device tree
  * @num_banks: Number of llcc banks
@@ -139,6 +140,7 @@  struct llcc_drv_data {
 	const struct llcc_slice_config *cfg;
 	const struct llcc_edac_reg_offset *edac_reg_offset;
 	struct mutex lock;
+	u32 cfg_index;
 	u32 cfg_size;
 	u32 max_slices;
 	u32 num_banks;