From b54ea82f01282253c85eb7e2fd2b6c96f7a027d8 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 7 Feb 2017 10:05:11 +0100 Subject: soc/fsl/qe: get rid of immrbar_virt_to_phys() immrbar_virt_to_phys() is not used anymore Signed-off-by: Christophe Leroy Acked-by: Li Yang Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/soc/fsl') diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index ade168f5328e..d9c04f588f7f 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -66,7 +66,7 @@ static unsigned int qe_num_of_snum; static phys_addr_t qebase = -1; -phys_addr_t get_qe_base(void) +static phys_addr_t get_qe_base(void) { struct device_node *qe; int ret; @@ -90,8 +90,6 @@ phys_addr_t get_qe_base(void) return qebase; } -EXPORT_SYMBOL(get_qe_base); - void qe_reset(void) { if (qe_immr == NULL) -- cgit From 2ccf80b7566cc035d903dd0ac5d7ebd25c2c1060 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:45 +0100 Subject: soc/fsl/qe: round brg_freq to 1kHz granularity Because of integer computation rounding in u-boot (that sets the QE brg-frequency DTS prop), the clk value is 99999999 Hz even though it is 100 MHz. When setting brg clks that are exact divisors of 100 MHz, this small differnce plays a role and can result in lower clks to be output (for instance 20 MHz - divide by 5 - results in 16.666 MHz - divide by 6). This patch fixes that by "forcing" the brg_clk to the nearest kHz when the difference is below 2 integer rounding errors (i.e. 4). Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/soc/fsl') diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index d9c04f588f7f..31a094573a9d 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -161,11 +161,15 @@ EXPORT_SYMBOL(qe_issue_cmd); */ static unsigned int brg_clk = 0; +#define CLK_GRAN (1000) +#define CLK_GRAN_LIMIT (5) + unsigned int qe_get_brg_clk(void) { struct device_node *qe; int size; const u32 *prop; + unsigned int mod; if (brg_clk) return brg_clk; @@ -183,6 +187,15 @@ unsigned int qe_get_brg_clk(void) of_node_put(qe); + /* round this if near to a multiple of CLK_GRAN */ + mod = brg_clk % CLK_GRAN; + if (mod) { + if (mod < CLK_GRAN_LIMIT) + brg_clk -= mod; + else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT)) + brg_clk += CLK_GRAN - mod; + } + return brg_clk; } EXPORT_SYMBOL(qe_get_brg_clk); -- cgit From e5c5c8d23fef2a976afe724f30e34da31be09769 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:46 +0100 Subject: soc/fsl/qe: only apply QE_General4 workaround on affected SoCs The QE_General4 workaround is only valid for the MPC832x and MPC836x SoCs. The other SoCs that embed a QUICC engine are not affected by this hardware bug and thus can use the computed divisors (this was successfully tested on the T1040). Similalry to what was done in commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR") in order to avoid changes in the device tree nodes of the QE (with maybe a variant of the compatible property), the PVR reg is read out to find out if the workaround must be applied or not. Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/soc/fsl') diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index 31a094573a9d..2ef6fc6487c1 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -200,6 +200,9 @@ unsigned int qe_get_brg_clk(void) } EXPORT_SYMBOL(qe_get_brg_clk); +#define PVR_VER_836x 0x8083 +#define PVR_VER_832x 0x8084 + /* Program the BRG to the given sampling rate and multiplier * * @brg: the BRG, QE_BRG1 - QE_BRG16 @@ -226,8 +229,9 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says that the BRG divisor must be even if you're not using divide-by-16 mode. */ - if (!div16 && (divisor & 1) && (divisor > 3)) - divisor++; + if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x)) + if (!div16 && (divisor & 1) && (divisor > 3)) + divisor++; tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE | div16; -- cgit From 4ba251626ff1ac3447f9a05ecfcec7f85b6c8a91 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:47 +0100 Subject: soc/fsl/qe: add EXPORT_SYMBOL for the 2 qe_tdm functions This allows to build the fsl_ucc_hdlc driver as a module. Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe_tdm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/soc/fsl') diff --git a/drivers/soc/fsl/qe/qe_tdm.c b/drivers/soc/fsl/qe/qe_tdm.c index a1048b44e6b9..f744c214f680 100644 --- a/drivers/soc/fsl/qe/qe_tdm.c +++ b/drivers/soc/fsl/qe/qe_tdm.c @@ -177,6 +177,7 @@ err_miss_siram_property: devm_iounmap(&pdev->dev, utdm->si_regs); return ret; } +EXPORT_SYMBOL(ucc_of_parse_tdm); void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info) { @@ -274,3 +275,4 @@ void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info) break; } } +EXPORT_SYMBOL(ucc_tdm_init); -- cgit From e21c7316d8ddcf1fd679591d1427e937999a7cf5 Mon Sep 17 00:00:00 2001 From: Roy Pledge Date: Mon, 17 Apr 2017 16:55:19 -0400 Subject: soc/fsl/qbman: Disable IRQs for deferred QBMan work Work for Congestion State Notifications (CSCN) and Message Ring (MR) handling is handled via the workqueue mechanism. This requires the driver to disable those IRQs before scheduling the work and re-enabling it once the work is completed so that the interrupt doesn't continually fire. Signed-off-by: Roy Pledge Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/soc/fsl') diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 6f509f68085e..2827a65aa25a 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1344,6 +1344,7 @@ static void qm_congestion_task(struct work_struct *work) if (!qm_mc_result_timeout(&p->p, &mcr)) { spin_unlock(&p->cgr_lock); dev_crit(p->config->dev, "QUERYCONGESTION timeout\n"); + qman_p_irqsource_add(p, QM_PIRQ_CSCI); return; } /* mask out the ones I'm not interested in */ @@ -1358,6 +1359,7 @@ static void qm_congestion_task(struct work_struct *work) if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid)) cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid)); spin_unlock(&p->cgr_lock); + qman_p_irqsource_add(p, QM_PIRQ_CSCI); } static void qm_mr_process_task(struct work_struct *work) @@ -1417,12 +1419,14 @@ static void qm_mr_process_task(struct work_struct *work) } qm_mr_cci_consume(&p->p, num); + qman_p_irqsource_add(p, QM_PIRQ_MRI); preempt_enable(); } static u32 __poll_portal_slow(struct qman_portal *p, u32 is) { if (is & QM_PIRQ_CSCI) { + qman_p_irqsource_remove(p, QM_PIRQ_CSCI); queue_work_on(smp_processor_id(), qm_portal_wq, &p->congestion_work); } @@ -1434,6 +1438,7 @@ static u32 __poll_portal_slow(struct qman_portal *p, u32 is) } if (is & QM_PIRQ_MRI) { + qman_p_irqsource_remove(p, QM_PIRQ_MRI); queue_work_on(smp_processor_id(), qm_portal_wq, &p->mr_work); } -- cgit