Message ID | 1522168309-12338-2-git-send-email-m-karicheri2@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Murali, On 03/27/2018 11:31 AM, Murali Karicheri wrote: > Navigator Subsystem (NSS) available on K2G SoC has a cut down > version of QMSS with less number of queues, internal linking ram > with lesser number of buffers etc. It doesn't have status and > explicit push register space as in QMSS available on other K2 SoCs. > So define reg indices specific to QMSS on K2G. This patch introduces > "keystone-navigator-qmss-l" compatibility to identify QMSS on > K2G NSS (QMSS Lite) and to customize the dts handling code. Per > Device manual, descriptors with index less than or equal to > regions0_size is in region 0 in the case of QMSS where as for > QMSS Lite, descriptors with index less than regions0_size is in > region 0. So update the size accordingly in the regions0_size bits > of the linking ram size 0 register. > > Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> > Signed-off-by: WingMan Kwok <w-kwok2@ti.com> > --- > .../bindings/soc/ti/keystone-navigator-qmss.txt | 7 ++ > drivers/soc/ti/knav_qmss.h | 6 ++ > drivers/soc/ti/knav_qmss_queue.c | 90 ++++++++++++++++------ > 3 files changed, 81 insertions(+), 22 deletions(-) > > diff --git a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt > index 77cd42c..1b0878a 100644 > --- a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt > +++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt > @@ -18,6 +18,7 @@ pool management. > > Required properties: > - compatible : Must be "ti,keystone-navigator-qmss"; > + : Must be "ti,keystone-navigator-qmss-l" for NSS Lite I think, It will be more accurate to add K2G specific compat string like "ti,66ak2g-navss-qm": compatible = "ti,66ak2g-navss-qm", "ti,keystone-navigator-qmss"; because 66ak2g TRM doesn't mention "Navss light" and this Navss version is used only in 66ak2g Soc. As result, 66ak2g Navss QM is subset of of keystone 2 Navss QM which should be defined in DT by adding more specific compat string in addition to generic one. > - clocks : phandle to the reference clock for this device. > - queue-range : <start number> total range of queue numbers for the device. > - linkram0 : <address size> for internal link ram, where size is the total > @@ -39,6 +40,12 @@ Required properties: > - Descriptor memory setup region. > - Queue Management/Queue Proxy region for queue Push. > - Queue Management/Queue Proxy region for queue Pop. > + > +For NSS lite, following QMSS reg indexes are used in that order For 66AK2G NAVSS QM.. > + - Queue Peek region. > + - Queue configuration region. > + - Queue Management/Queue Proxy region for queue Push/Pop. > + > - queue-pools : child node classifying the queue ranges into pools. > Queue ranges are grouped into 3 type of pools: > - qpend : pool of qpend(interruptible) queues > diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h > index 905b974..5fa1ce6 100644 > --- a/drivers/soc/ti/knav_qmss.h > +++ b/drivers/soc/ti/knav_qmss.h > @@ -292,6 +292,11 @@ struct knav_queue { > struct list_head list; > }; > > +enum qmss_version { > + QMSS, > + QMSS_LITE, QMSS_66AK2G > +}; > + > struct knav_device { > struct device *dev; > unsigned base_id; > @@ -305,6 +310,7 @@ struct knav_device { > struct list_head pools; > struct list_head pdsps; > struct list_head qmgrs; > + enum qmss_version version; > }; > [...] > } > > +/* Match table for of_platform binding */ > +static const struct of_device_id keystone_qmss_of_match[] = { > + { > + .compatible = "ti,keystone-navigator-qmss", .data = (void *)QMSS, > + }, > + { > + .compatible = "ti,keystone-navigator-qmss-l", > + .data = (void *)QMSS_LITE, > + }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); > + > static int knav_queue_probe(struct platform_device *pdev) > { > struct device_node *node = pdev->dev.of_node; > struct device_node *qmgrs, *queue_pools, *regions, *pdsps; > + const struct of_device_id *match; > struct device *dev = &pdev->dev; > u32 temp[2]; > int ret; > @@ -1700,6 +1749,10 @@ static int knav_queue_probe(struct platform_device *pdev) > return -ENOMEM; > } > > + match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev); > + if (match && match->data) > + kdev->version = QMSS_LITE; if (match) kdev->version = match->data; else error? [...]
Hi Grygorii, Thanks for reviewing this! On 03/28/2018 03:01 PM, Grygorii Strashko wrote: > Hi Murali, > > On 03/27/2018 11:31 AM, Murali Karicheri wrote: >> Navigator Subsystem (NSS) available on K2G SoC has a cut down >> version of QMSS with less number of queues, internal linking ram >> with lesser number of buffers etc. It doesn't have status and >> explicit push register space as in QMSS available on other K2 SoCs. >> So define reg indices specific to QMSS on K2G. This patch introduces >> "keystone-navigator-qmss-l" compatibility to identify QMSS on >> K2G NSS (QMSS Lite) and to customize the dts handling code. Per >> Device manual, descriptors with index less than or equal to >> regions0_size is in region 0 in the case of QMSS where as for >> QMSS Lite, descriptors with index less than regions0_size is in >> region 0. So update the size accordingly in the regions0_size bits >> of the linking ram size 0 register. >> >> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> >> Signed-off-by: WingMan Kwok <w-kwok2@ti.com> >> --- >> .../bindings/soc/ti/keystone-navigator-qmss.txt | 7 ++ >> drivers/soc/ti/knav_qmss.h | 6 ++ >> drivers/soc/ti/knav_qmss_queue.c | 90 ++++++++++++++++------ >> 3 files changed, 81 insertions(+), 22 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt >> index 77cd42c..1b0878a 100644 >> --- a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt >> +++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt >> @@ -18,6 +18,7 @@ pool management. >> >> Required properties: >> - compatible : Must be "ti,keystone-navigator-qmss"; >> + : Must be "ti,keystone-navigator-qmss-l" for NSS Lite > > > I think, It will be more accurate to add K2G specific compat string > like "ti,66ak2g-navss-qm": > > compatible = "ti,66ak2g-navss-qm", "ti,keystone-navigator-qmss"; > > because 66ak2g TRM doesn't mention "Navss light" and this Navss version is used > only in 66ak2g Soc. As result, 66ak2g Navss QM is subset of of keystone 2 Navss QM > which should be defined in DT by adding more specific compat string in addition > to generic one. > As I have mentioned in the commit description, it is not a subset of the K2 registers. There are some differences that makes it not compatible with K2 QMSS. See my description, >>It doesn't have status and explicit push register space as in QMSS available on >>other K2 SoCs. And also >> Per Device manual, descriptors with index less than or equal to >> regions0_size is in region 0 in the case of QMSS where as for >> QMSS Lite, descriptors with index less than regions0_size is in >> region 0. So update the size accordingly in the regions0_size bits >> of the linking ram size 0 register So will have to use a specific compatible = "ti,66ak2g-navss-qm" for this QM IMO. Murali > >> - clocks : phandle to the reference clock for this device. >> - queue-range : <start number> total range of queue numbers for the device. >> - linkram0 : <address size> for internal link ram, where size is the total >> @@ -39,6 +40,12 @@ Required properties: >> - Descriptor memory setup region. >> - Queue Management/Queue Proxy region for queue Push. >> - Queue Management/Queue Proxy region for queue Pop. >> + >> +For NSS lite, following QMSS reg indexes are used in that order > > For 66AK2G NAVSS QM.. > >> + - Queue Peek region. >> + - Queue configuration region. >> + - Queue Management/Queue Proxy region for queue Push/Pop. >> + >> - queue-pools : child node classifying the queue ranges into pools. >> Queue ranges are grouped into 3 type of pools: >> - qpend : pool of qpend(interruptible) queues >> diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h >> index 905b974..5fa1ce6 100644 >> --- a/drivers/soc/ti/knav_qmss.h >> +++ b/drivers/soc/ti/knav_qmss.h >> @@ -292,6 +292,11 @@ struct knav_queue { >> struct list_head list; >> }; >> >> +enum qmss_version { >> + QMSS, >> + QMSS_LITE, > > QMSS_66AK2G > >> +}; >> + >> struct knav_device { >> struct device *dev; >> unsigned base_id; >> @@ -305,6 +310,7 @@ struct knav_device { >> struct list_head pools; >> struct list_head pdsps; >> struct list_head qmgrs; >> + enum qmss_version version; >> }; >> > > [...] > >> } >> >> +/* Match table for of_platform binding */ >> +static const struct of_device_id keystone_qmss_of_match[] = { >> + { >> + .compatible = "ti,keystone-navigator-qmss", > > .data = (void *)QMSS, > >> + }, >> + { >> + .compatible = "ti,keystone-navigator-qmss-l", >> + .data = (void *)QMSS_LITE, >> + }, >> + {}, >> +}; >> +MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); >> + >> static int knav_queue_probe(struct platform_device *pdev) >> { >> struct device_node *node = pdev->dev.of_node; >> struct device_node *qmgrs, *queue_pools, *regions, *pdsps; >> + const struct of_device_id *match; >> struct device *dev = &pdev->dev; >> u32 temp[2]; >> int ret; >> @@ -1700,6 +1749,10 @@ static int knav_queue_probe(struct platform_device *pdev) >> return -ENOMEM; >> } >> >> + match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev); >> + if (match && match->data) >> + kdev->version = QMSS_LITE; > > if (match) > kdev->version = match->data; > else > error? > [...] >
On 03/28/2018 03:01 PM, Grygorii Strashko wrote: > Hi Murali, > >> >> +enum qmss_version { >> + QMSS, >> + QMSS_LITE, > > QMSS_66AK2G > OK. >> +}; >> + >> struct knav_device { >> struct device *dev; >> unsigned base_id; >> @@ -305,6 +310,7 @@ struct knav_device { >> struct list_head pools; >> struct list_head pdsps; >> struct list_head qmgrs; >> + enum qmss_version version; >> }; >> > > [...] > >> } >> >> +/* Match table for of_platform binding */ >> +static const struct of_device_id keystone_qmss_of_match[] = { >> + { >> + .compatible = "ti,keystone-navigator-qmss", > > .data = (void *)QMSS, This seems to be unnecessary as QMSS is actually defined as zero. Also this static. So that value is zero already in memory. > >> + }, >> + { >> + .compatible = "ti,keystone-navigator-qmss-l", >> + .data = (void *)QMSS_LITE, >> + }, >> + {}, >> +}; >> +MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); >> + >> static int knav_queue_probe(struct platform_device *pdev) >> { >> struct device_node *node = pdev->dev.of_node; >> struct device_node *qmgrs, *queue_pools, *regions, *pdsps; >> + const struct of_device_id *match; >> struct device *dev = &pdev->dev; >> u32 temp[2]; >> int ret; >> @@ -1700,6 +1749,10 @@ static int knav_queue_probe(struct platform_device *pdev) >> return -ENOMEM; >> } >> >> + match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev); >> + if (match && match->data) >> + kdev->version = QMSS_LITE; > > if (match) > kdev->version = match->data; > else > error? Similar to above. This private memory is allocated using kzalloc which initializes everything to zero. So the else part is unnecessary. Murali > [...] >
diff --git a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt index 77cd42c..1b0878a 100644 --- a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt +++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt @@ -18,6 +18,7 @@ pool management. Required properties: - compatible : Must be "ti,keystone-navigator-qmss"; + : Must be "ti,keystone-navigator-qmss-l" for NSS Lite - clocks : phandle to the reference clock for this device. - queue-range : <start number> total range of queue numbers for the device. - linkram0 : <address size> for internal link ram, where size is the total @@ -39,6 +40,12 @@ Required properties: - Descriptor memory setup region. - Queue Management/Queue Proxy region for queue Push. - Queue Management/Queue Proxy region for queue Pop. + +For NSS lite, following QMSS reg indexes are used in that order + - Queue Peek region. + - Queue configuration region. + - Queue Management/Queue Proxy region for queue Push/Pop. + - queue-pools : child node classifying the queue ranges into pools. Queue ranges are grouped into 3 type of pools: - qpend : pool of qpend(interruptible) queues diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h index 905b974..5fa1ce6 100644 --- a/drivers/soc/ti/knav_qmss.h +++ b/drivers/soc/ti/knav_qmss.h @@ -292,6 +292,11 @@ struct knav_queue { struct list_head list; }; +enum qmss_version { + QMSS, + QMSS_LITE, +}; + struct knav_device { struct device *dev; unsigned base_id; @@ -305,6 +310,7 @@ struct knav_device { struct list_head pools; struct list_head pdsps; struct list_head qmgrs; + enum qmss_version version; }; struct knav_range_ops { diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 77d6b5c..5b2c4e9 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -42,6 +42,15 @@ #define KNAV_QUEUE_PUSH_REG_INDEX 4 #define KNAV_QUEUE_POP_REG_INDEX 5 +/* Queue manager register indices in DTS for QMSS in NSS lite. + * There are no status and vbusm push registers on this version + * QMSS. Push registers are same as pop, So all indices above 1 + * are to be re-defined + */ +#define KNAV_L_QUEUE_CONFIG_REG_INDEX 1 +#define KNAV_L_QUEUE_REGION_REG_INDEX 2 +#define KNAV_L_QUEUE_PUSH_REG_INDEX 3 + /* PDSP register indices in DTS */ #define KNAV_QUEUE_PDSP_IRAM_REG_INDEX 0 #define KNAV_QUEUE_PDSP_REGS_REG_INDEX 1 @@ -1169,8 +1178,12 @@ static int knav_queue_setup_link_ram(struct knav_device *kdev) dev_dbg(kdev->dev, "linkram0: dma:%pad, virt:%p, size:%x\n", &block->dma, block->virt, block->size); writel_relaxed((u32)block->dma, &qmgr->reg_config->link_ram_base0); - writel_relaxed(block->size, &qmgr->reg_config->link_ram_size0); - + if (kdev->version == QMSS_LITE) + writel_relaxed(block->size, + &qmgr->reg_config->link_ram_size0); + else + writel_relaxed(block->size - 1, + &qmgr->reg_config->link_ram_size0); block++; if (!block->size) continue; @@ -1387,42 +1400,64 @@ static int knav_queue_init_qmgrs(struct knav_device *kdev, qmgr->reg_peek = knav_queue_map_reg(kdev, child, KNAV_QUEUE_PEEK_REG_INDEX); - qmgr->reg_status = - knav_queue_map_reg(kdev, child, - KNAV_QUEUE_STATUS_REG_INDEX); + + if (kdev->version == QMSS) { + qmgr->reg_status = + knav_queue_map_reg(kdev, child, + KNAV_QUEUE_STATUS_REG_INDEX); + } + qmgr->reg_config = knav_queue_map_reg(kdev, child, + (kdev->version == QMSS_LITE) ? + KNAV_L_QUEUE_CONFIG_REG_INDEX : KNAV_QUEUE_CONFIG_REG_INDEX); qmgr->reg_region = knav_queue_map_reg(kdev, child, + (kdev->version == QMSS_LITE) ? + KNAV_L_QUEUE_REGION_REG_INDEX : KNAV_QUEUE_REGION_REG_INDEX); + qmgr->reg_push = knav_queue_map_reg(kdev, child, - KNAV_QUEUE_PUSH_REG_INDEX); - qmgr->reg_pop = - knav_queue_map_reg(kdev, child, - KNAV_QUEUE_POP_REG_INDEX); + (kdev->version == QMSS_LITE) ? + KNAV_L_QUEUE_PUSH_REG_INDEX : + KNAV_QUEUE_PUSH_REG_INDEX); + + if (kdev->version == QMSS) { + qmgr->reg_pop = + knav_queue_map_reg(kdev, child, + KNAV_QUEUE_POP_REG_INDEX); + } - if (IS_ERR(qmgr->reg_peek) || IS_ERR(qmgr->reg_status) || + if (IS_ERR(qmgr->reg_peek) || + ((kdev->version == QMSS) && + (IS_ERR(qmgr->reg_status) || IS_ERR(qmgr->reg_pop))) || IS_ERR(qmgr->reg_config) || IS_ERR(qmgr->reg_region) || - IS_ERR(qmgr->reg_push) || IS_ERR(qmgr->reg_pop)) { + IS_ERR(qmgr->reg_push)) { dev_err(dev, "failed to map qmgr regs\n"); + if (kdev->version == QMSS) { + if (!IS_ERR(qmgr->reg_status)) + devm_iounmap(dev, qmgr->reg_status); + if (!IS_ERR(qmgr->reg_pop)) + devm_iounmap(dev, qmgr->reg_pop); + } if (!IS_ERR(qmgr->reg_peek)) devm_iounmap(dev, qmgr->reg_peek); - if (!IS_ERR(qmgr->reg_status)) - devm_iounmap(dev, qmgr->reg_status); if (!IS_ERR(qmgr->reg_config)) devm_iounmap(dev, qmgr->reg_config); if (!IS_ERR(qmgr->reg_region)) devm_iounmap(dev, qmgr->reg_region); if (!IS_ERR(qmgr->reg_push)) devm_iounmap(dev, qmgr->reg_push); - if (!IS_ERR(qmgr->reg_pop)) - devm_iounmap(dev, qmgr->reg_pop); devm_kfree(dev, qmgr); continue; } + /* Use same push register for pop as well */ + if (kdev->version == QMSS_LITE) + qmgr->reg_pop = qmgr->reg_push; + list_add_tail(&qmgr->list, &kdev->qmgrs); dev_info(dev, "added qmgr start queue %d, num of queues %d, reg_peek %p, reg_status %p, reg_config %p, reg_region %p, reg_push %p, reg_pop %p\n", qmgr->start_queue, qmgr->num_queues, @@ -1681,10 +1716,24 @@ static int knav_queue_init_queues(struct knav_device *kdev) return 0; } +/* Match table for of_platform binding */ +static const struct of_device_id keystone_qmss_of_match[] = { + { + .compatible = "ti,keystone-navigator-qmss", + }, + { + .compatible = "ti,keystone-navigator-qmss-l", + .data = (void *)QMSS_LITE, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); + static int knav_queue_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct device_node *qmgrs, *queue_pools, *regions, *pdsps; + const struct of_device_id *match; struct device *dev = &pdev->dev; u32 temp[2]; int ret; @@ -1700,6 +1749,10 @@ static int knav_queue_probe(struct platform_device *pdev) return -ENOMEM; } + match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev); + if (match && match->data) + kdev->version = QMSS_LITE; + platform_set_drvdata(pdev, kdev); kdev->dev = dev; INIT_LIST_HEAD(&kdev->queue_ranges); @@ -1815,13 +1868,6 @@ static int knav_queue_remove(struct platform_device *pdev) return 0; } -/* Match table for of_platform binding */ -static struct of_device_id keystone_qmss_of_match[] = { - { .compatible = "ti,keystone-navigator-qmss", }, - {}, -}; -MODULE_DEVICE_TABLE(of, keystone_qmss_of_match); - static struct platform_driver keystone_qmss_driver = { .probe = knav_queue_probe, .remove = knav_queue_remove,