Those patches effectively ensure that all inputs are routed to CSI_MEM0, which will not work for my usecase: I currently have parallel capture on IPU0 CSI0 and MIPI capture on IPU0 CSI1 (virtual channel = 1). My current _ipu_smfc_init() and _ipu_csi_set_mipi_di() look like:
void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
{
uint32_t temp;
uint32_t id = channel; // Temporary hack: Presuming that CSI_MEM0 thru CSI_MEM3 are 0 thru 3 and that MIPI VC will be mapped to matching CSI_MEMn
temp = ipu_smfc_read(ipu, SMFC_MAP);
switch (channel) {
case CSI_MEM0:
temp &= ~SMFC_MAP_CH0_MASK;
temp |= ((csi << 2) | id) << SMFC_MAP_CH0_SHIFT;
break;
case CSI_MEM1:
temp &= ~SMFC_MAP_CH1_MASK;
temp |= ((csi << 2) | id) << SMFC_MAP_CH1_SHIFT;
break;
case CSI_MEM2:
temp &= ~SMFC_MAP_CH2_MASK;
temp |= ((csi << 2) | id) << SMFC_MAP_CH2_SHIFT;
break;
case CSI_MEM3:
temp &= ~SMFC_MAP_CH3_MASK;
temp |= ((csi << 2) | id) << SMFC_MAP_CH3_SHIFT;
break;
default:
return;
}
ipu_smfc_write(ipu, temp, SMFC_MAP);
}
int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi)
{
uint32_t temp;
int retval = 0;
if (di_val > 0xFFL) {
retval = -EINVAL;
goto err;
}
temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI);
switch (num) {
case IPU_CSI_MIPI_DI0:
temp &= ~CSI_MIPI_DI0_MASK;
temp |= (di_val << CSI_MIPI_DI0_SHIFT);
ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
break;
case IPU_CSI_MIPI_DI1:
temp &= ~CSI_MIPI_DI1_MASK;
temp |= (di_val << CSI_MIPI_DI1_SHIFT);
ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
break;
case IPU_CSI_MIPI_DI2:
temp &= ~CSI_MIPI_DI2_MASK;
temp |= (di_val << CSI_MIPI_DI2_SHIFT);
ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
break;
case IPU_CSI_MIPI_DI3:
temp &= ~CSI_MIPI_DI3_MASK;
temp |= (di_val << CSI_MIPI_DI3_SHIFT);
ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
break;
default:
retval = -EINVAL;
}
err:
return retval;
}
Experimentally trying the patches produced the same frame-sync issue as described above.