Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: ti: k3-udma: Workaround errata i2234

Per [1], UDMA TR15 transactions may hang if ICNT0 is less than 64B
Work around is to set EOL flag is to 1 for ICNT0.

Since, there is no performance penalty / side effects of setting EOL
flag event ICNTO > 64B, just set the flag for all UDMAP TR15
descriptors.

[1] https://www.ti.com/lit/er/sprz455a/sprz455a.pdf
Errata doc for J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0
(Rev. A)

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
[j-choudhary@ti.com: minor cleanups]
Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
Link: https://lore.kernel.org/r/20230323120107.27638-1-j-choudhary@ti.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Vignesh Raghavendra and committed by
Vinod Koul
f806bea3 86de3bbf

+12 -9
+11 -9
drivers/dma/ti/k3-udma.c
··· 2966 2966 struct scatterlist *sgent; 2967 2967 struct cppi5_tr_type15_t *tr_req = NULL; 2968 2968 enum dma_slave_buswidth dev_width; 2969 + u32 csf = CPPI5_TR_CSF_SUPR_EVT; 2969 2970 u16 tr_cnt0, tr_cnt1; 2970 2971 dma_addr_t dev_addr; 2971 2972 struct udma_desc *d; ··· 3037 3036 3038 3037 if (uc->ud->match_data->type == DMA_TYPE_UDMA) { 3039 3038 asel = 0; 3039 + csf |= CPPI5_TR_CSF_EOL_ICNT0; 3040 3040 } else { 3041 3041 asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; 3042 3042 dev_addr |= asel; ··· 3061 3059 3062 3060 cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, false, 3063 3061 true, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3064 - cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT); 3062 + cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf); 3065 3063 cppi5_tr_set_trigger(&tr_req[tr_idx].flags, 3066 3064 uc->config.tr_trigger_type, 3067 3065 CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, 0, 0); ··· 3107 3105 cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, 3108 3106 false, true, 3109 3107 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3110 - cppi5_tr_csf_set(&tr_req[tr_idx].flags, 3111 - CPPI5_TR_CSF_SUPR_EVT); 3108 + cppi5_tr_csf_set(&tr_req[tr_idx].flags, csf); 3112 3109 cppi5_tr_set_trigger(&tr_req[tr_idx].flags, 3113 3110 uc->config.tr_trigger_type, 3114 3111 CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, ··· 3151 3150 d->residue += sg_len; 3152 3151 } 3153 3152 3154 - cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, 3155 - CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); 3153 + cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, csf | CPPI5_TR_CSF_EOP); 3156 3154 3157 3155 return d; 3158 3156 } ··· 3680 3680 int num_tr; 3681 3681 size_t tr_size = sizeof(struct cppi5_tr_type15_t); 3682 3682 u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; 3683 + u32 csf = CPPI5_TR_CSF_SUPR_EVT; 3683 3684 3684 3685 if (uc->config.dir != DMA_MEM_TO_MEM) { 3685 3686 dev_err(chan->device->dev, ··· 3711 3710 if (uc->ud->match_data->type != DMA_TYPE_UDMA) { 3712 3711 src |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; 3713 3712 dest |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; 3713 + } else { 3714 + csf |= CPPI5_TR_CSF_EOL_ICNT0; 3714 3715 } 3715 3716 3716 3717 tr_req = d->hwdesc[0].tr_req_base; 3717 3718 3718 3719 cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true, 3719 3720 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3720 - cppi5_tr_csf_set(&tr_req[0].flags, CPPI5_TR_CSF_SUPR_EVT); 3721 + cppi5_tr_csf_set(&tr_req[0].flags, csf); 3721 3722 3722 3723 tr_req[0].addr = src; 3723 3724 tr_req[0].icnt0 = tr0_cnt0; ··· 3738 3735 if (num_tr == 2) { 3739 3736 cppi5_tr_init(&tr_req[1].flags, CPPI5_TR_TYPE15, false, true, 3740 3737 CPPI5_TR_EVENT_SIZE_COMPLETION, 0); 3741 - cppi5_tr_csf_set(&tr_req[1].flags, CPPI5_TR_CSF_SUPR_EVT); 3738 + cppi5_tr_csf_set(&tr_req[1].flags, csf); 3742 3739 3743 3740 tr_req[1].addr = src + tr0_cnt1 * tr0_cnt0; 3744 3741 tr_req[1].icnt0 = tr1_cnt0; ··· 3753 3750 tr_req[1].dicnt3 = 1; 3754 3751 } 3755 3752 3756 - cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, 3757 - CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); 3753 + cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, csf | CPPI5_TR_CSF_EOP); 3758 3754 3759 3755 if (uc->config.metadata_size) 3760 3756 d->vd.tx.metadata_ops = &metadata_ops;
+1
include/linux/dma/ti-cppi5.h
··· 616 616 #define CPPI5_TR_CSF_SUPR_EVT BIT(2) 617 617 #define CPPI5_TR_CSF_EOL_ADV_SHIFT (4U) 618 618 #define CPPI5_TR_CSF_EOL_ADV_MASK GENMASK(6, 4) 619 + #define CPPI5_TR_CSF_EOL_ICNT0 BIT(4) 619 620 #define CPPI5_TR_CSF_EOP BIT(7) 620 621 621 622 /**