1919#include <linux/spinlock.h>
2020#include <linux/slab.h>
2121#include <linux/types.h>
22+ #include <linux/firmware/qcom/qcom_scm.h>
23+ #include <linux/soc/qcom/qcom_aoss.h>
2224
2325#define PDC_MAX_GPIO_IRQS 256
2426#define PDC_DRV_OFFSET 0x10000
2527
2628/* Valid only on HW version < 3.2 */
2729#define IRQ_ENABLE_BANK 0x10
2830#define IRQ_ENABLE_BANK_MAX (IRQ_ENABLE_BANK + BITS_TO_BYTES(PDC_MAX_GPIO_IRQS))
31+ #define IRQ_i_CFG_IRQ_MASK_3_0 3
2932#define IRQ_i_CFG 0x110
3033
3134/* Valid only on HW version >= 3.2 */
35+ #define IRQ_i_CFG_IRQ_MASK_3_2 4
3236#define IRQ_i_CFG_IRQ_ENABLE 3
3337
3438#define IRQ_i_CFG_TYPE_MASK GENMASK(2, 0)
3539
3640#define PDC_VERSION_REG 0x1000
3741
3842/* Notable PDC versions */
43+ #define PDC_VERSION_3_0 0x30000
3944#define PDC_VERSION_3_2 0x30200
4045
46+ #define PDC_PASS_THROUGH_MODE 0
47+
4148struct pdc_pin_region {
4249 u32 pin_base ;
4350 u32 parent_base ;
@@ -97,6 +104,33 @@ static void pdc_x1e_irq_enable_write(u32 bank, u32 enable)
97104 pdc_base_reg_write (base , IRQ_ENABLE_BANK , bank , enable );
98105}
99106
107+ /*
108+ * The new mask bit controls whether the interrupt is to be forwarded to the
109+ * parent GIC in secondary controller mode. Writing the mask is do not care
110+ * when the PDC is set to pass through mode.
111+ *
112+ * As linux only makes so far make use of pass through mode set all IRQs
113+ * masked during probe.
114+ */
115+ static void __pdc_mask_intr (int pin_out , bool mask )
116+ {
117+ unsigned long irq_cfg ;
118+ int mask_bit ;
119+
120+ /* Mask bit available from v3.0 */
121+ if (pdc_version < PDC_VERSION_3_0 )
122+ return ;
123+
124+ if (pdc_version < PDC_VERSION_3_2 )
125+ mask_bit = IRQ_i_CFG_IRQ_MASK_3_0 ;
126+ else
127+ mask_bit = IRQ_i_CFG_IRQ_MASK_3_2 ;
128+
129+ irq_cfg = pdc_reg_read (IRQ_i_CFG , pin_out );
130+ __assign_bit (mask_bit , & irq_cfg , mask );
131+ pdc_reg_write (IRQ_i_CFG , pin_out , irq_cfg );
132+ }
133+
100134static void __pdc_enable_intr (int pin_out , bool on )
101135{
102136 unsigned long enable ;
@@ -312,7 +346,6 @@ static const struct irq_domain_ops qcom_pdc_ops = {
312346static int pdc_setup_pin_mapping (struct device_node * np )
313347{
314348 int ret , n , i ;
315-
316349 n = of_property_count_elems_of_size (np , "qcom,pdc-ranges" , sizeof (u32 ));
317350 if (n <= 0 || n % 3 )
318351 return - EINVAL ;
@@ -341,8 +374,10 @@ static int pdc_setup_pin_mapping(struct device_node *np)
341374 if (ret )
342375 return ret ;
343376
344- for (i = 0 ; i < pdc_region [n ].cnt ; i ++ )
377+ for (i = 0 ; i < pdc_region [n ].cnt ; i ++ ) {
345378 __pdc_enable_intr (i + pdc_region [n ].pin_base , 0 );
379+ __pdc_mask_intr (i + pdc_region [n ].pin_base , true);
380+ }
346381 }
347382
348383 return 0 ;
@@ -352,10 +387,13 @@ static int pdc_setup_pin_mapping(struct device_node *np)
352387
353388static int qcom_pdc_probe (struct platform_device * pdev , struct device_node * parent )
354389{
390+ static const char buf [64 ] = "{class: cx_mol, res: cx, val: mol}" ;
391+ unsigned int domain_flag = IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP ;
355392 struct irq_domain * parent_domain , * pdc_domain ;
356393 struct device_node * node = pdev -> dev .of_node ;
357394 resource_size_t res_size ;
358395 struct resource res ;
396+ struct qmp * pdc_qmp ;
359397 int ret ;
360398
361399 /* compat with old sm8150 DT which had very small region for PDC */
@@ -366,6 +404,13 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare
366404 if (res_size > resource_size (& res ))
367405 pr_warn ("%pOF: invalid reg size, please fix DT\n" , node );
368406
407+ pdc_base = ioremap (res .start , res_size );
408+ if (!pdc_base ) {
409+ pr_err ("%pOF: unable to map PDC registers\n" , node );
410+ ret = - ENXIO ;
411+ goto fail ;
412+ }
413+
369414 /*
370415 * PDC has multiple DRV regions, each one provides the same set of
371416 * registers for a particular client in the system. Due to a hardware
@@ -382,15 +427,71 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare
382427 }
383428
384429 pdc_x1e_quirk = true;
385- }
386430
387- pdc_base = ioremap (res .start , res_size );
388- if (!pdc_base ) {
389- pr_err ("%pOF: unable to map PDC registers\n" , node );
390- ret = - ENXIO ;
391- goto fail ;
431+ /*
432+ * There are two modes PDC irqchip can work in
433+ * - pass through mode
434+ * - secondary controller mode
435+ *
436+ * All PDC irqchip supports pass through mode in which both
437+ * Direct SPIs and GPIO IRQs (as SPIs) are sent to GIC
438+ * without latching at PDC.
439+ *
440+ * Newer PDCs (v3.0 onwards) also support additional
441+ * secondary controller mode where PDC latches GPIO IRQs
442+ * and sends to GIC as level type IRQ. Direct SPIs still
443+ * works same as pass through mode without latching at PDC
444+ * even in secondary controller mode.
445+ *
446+ * All the SoCs so far default uses pass through mode with
447+ * the exception of x1e.
448+ *
449+ * x1e modes:
450+ *
451+ * x1e PDC may be set to secondary controller mode for
452+ * builds on CRD boards whereas it may be set to pass
453+ * through mode for IoT-EVK boards.
454+ *
455+ * There is no way to read which current mode it is set to
456+ * and make PDC work in respective mode as the read access
457+ * is not opened up for non secure world. There is though
458+ * write access opened up via SCM write API to set the mode.
459+ *
460+ * Configure PDC mode to pass through mode for all x1e based
461+ * boards.
462+ *
463+ * For successful write:
464+ * - Nothing more to be done
465+ *
466+ * For unsuccessful write:
467+ * - Inform TLMM to monitor GPIO IRQs (same as MPM)
468+ * - Prevent SoC low power mode (CxPC) as PDC is not
469+ * monitoring GPIO IRQs which may be needed to wake
470+ * the SoC from low power mode.
471+ */
472+ ret = of_address_to_resource (node , 2 , & res );
473+ if (ret ) {
474+ domain_flag = IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP ;
475+ goto skip_scm_write ;
476+ }
477+
478+ ret = qcom_scm_io_writel (res .start , PDC_PASS_THROUGH_MODE );
479+ if (ret ) {
480+ pdc_qmp = qmp_get (& pdev -> dev );
481+ if (IS_ERR (pdc_qmp )) {
482+ ret = PTR_ERR (pdc_qmp );
483+ goto fail ;
484+ } else {
485+ ret = qmp_send (pdc_qmp , buf , sizeof (buf ));
486+ qmp_put (pdc_qmp );
487+ if (ret )
488+ goto fail ;
489+ }
490+ domain_flag = IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP ;
491+ }
392492 }
393493
494+ skip_scm_write :
394495 pdc_version = pdc_reg_read (PDC_VERSION_REG , 0 );
395496
396497 parent_domain = irq_find_host (parent );
@@ -407,7 +508,7 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare
407508 }
408509
409510 pdc_domain = irq_domain_create_hierarchy (parent_domain ,
410- IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP ,
511+ domain_flag ,
411512 PDC_MAX_GPIO_IRQS ,
412513 of_fwnode_handle (node ),
413514 & qcom_pdc_ops , NULL );
0 commit comments