On Wed, 26 Apr 2023 14:51:12 +0300, Tomi Valkeinen wrote: [...] > +static int ub960_configure_ports_for_streaming(struct ub960_data *priv, > + struct v4l2_subdev_state *state) > +{ > + u8 fwd_ctl; > + struct { > + u32 num_streams; > + u8 pixel_dt; > + u8 meta_dt; > + u32 meta_lines; > + u32 tx_port; > + } rx_data[UB960_MAX_RX_NPORTS] = {}; > + u8 vc_map[UB960_MAX_RX_NPORTS] = {}; > + struct v4l2_subdev_route *route; > + unsigned int nport; > + int ret; > + > + ret = ub960_validate_stream_vcs(priv); > + if (ret) > + return ret; > + > + ub960_get_vc_maps(priv, state, vc_map); > + > + for_each_active_route(&state->routing, route) { > + struct ub960_rxport *rxport; > + struct ub960_txport *txport; > + struct v4l2_mbus_framefmt *fmt; > + const struct ub960_format_info *ub960_fmt; > + unsigned int nport; > + > + nport = ub960_pad_to_port(priv, route->sink_pad); > + > + rxport = priv->rxports[nport]; > + if (!rxport) > + return -EINVAL; > + > + txport = priv->txports[ub960_pad_to_port(priv, route->source_pad)]; > + if (!txport) > + return -EINVAL; > + > + rx_data[nport].tx_port = ub960_pad_to_port(priv, route->source_pad); > + > + rx_data[nport].num_streams++; > + > + /* For the rest, we are only interested in parallel busses */ > + if (rxport->rx_mode == RXPORT_MODE_CSI2_SYNC || > + rxport->rx_mode == RXPORT_MODE_CSI2_ASYNC) > + continue; > + > + if (rx_data[nport].num_streams > 2) > + return -EPIPE; > + > + fmt = v4l2_subdev_state_get_stream_format(state, > + route->sink_pad, > + route->sink_stream); > + if (!fmt) > + return -EPIPE; > + > + ub960_fmt = ub960_find_format(fmt->code); > + if (!ub960_fmt) > + return -EPIPE; > + > + if (ub960_fmt->meta) { > + if (fmt->height > 3) { > + dev_err(&priv->client->dev, > + "rx%u: unsupported metadata height %u\n", > + nport, fmt->height); > + return -EPIPE; > + } > + > + rx_data[nport].meta_dt = ub960_fmt->datatype; > + rx_data[nport].meta_lines = fmt->height; > + } else { > + rx_data[nport].pixel_dt = ub960_fmt->datatype; > + } > + } > + > + /* Configure RX ports */ > + > + fwd_ctl = 0; Hello, I have only used the first RX port in my setup (ds90ub933 to ds90ub964). The logic for activating/deactivating the Rx ports did not work for me. My suggestion is: - fwd_ctl = 0; + fwd_ctl = 0xF0; /* Default: Disable forwarding for all RX ports */ > + > + for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { > + struct ub960_rxport *rxport = priv->rxports[nport]; > + u8 vc = vc_map[nport]; > + > + if (rx_data[nport].num_streams == 0) > + continue; > + > + switch (rxport->rx_mode) { > + case RXPORT_MODE_RAW10: > + ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID, > + rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT)); > + > + ub960_rxport_write(priv, rxport->nport, > + UB960_RR_RAW_EMBED_DTYPE, > + (rx_data[nport].meta_lines << UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT) | > + rx_data[nport].meta_dt); > + > + break; > + > + case RXPORT_MODE_RAW12_HF: > + case RXPORT_MODE_RAW12_LF: > + /* Not implemented */ > + break; > + > + case RXPORT_MODE_CSI2_SYNC: > + case RXPORT_MODE_CSI2_ASYNC: > + if (!priv->hw_data->is_ub9702) { > + /* Map all VCs from this port to the same VC */ > + ub960_rxport_write(priv, nport, UB960_RR_CSI_VC_MAP, > + (vc << UB960_RR_CSI_VC_MAP_SHIFT(3)) | > + (vc << UB960_RR_CSI_VC_MAP_SHIFT(2)) | > + (vc << UB960_RR_CSI_VC_MAP_SHIFT(1)) | > + (vc << UB960_RR_CSI_VC_MAP_SHIFT(0))); > + } else { > + unsigned int i; > + > + /* Map all VCs from this port to VC(nport) */ > + for (i = 0; i < 8; i++) > + ub960_rxport_write(priv, nport, > + UB960_RR_VC_ID_MAP(i), > + nport); > + } > + > + break; > + } > + > + /* Forwarding */ > + > + fwd_ctl |= BIT(4 + nport); /* forward disable */ - fwd_ctl |= BIT(4 + nport); /* forward disable */ + fwd_ctl &= ~UB960_SR_FWD_CTL1_PORT_DIS(nport); /* clear disable + forwarding */ According to the data sheet, the ds90ub960 and the ds90ub964 should be identical, so this change should fit both devices. > + if (rx_data[nport].tx_port == 1) > + fwd_ctl |= BIT(nport); /* forward to TX1 */ > + else > + fwd_ctl &= ~BIT(nport); /* forward to TX0 */ > + } > + > + ub960_write(priv, UB960_SR_FWD_CTL1, fwd_ctl); > + > + return 0; > +} [...] Thanks and regards, Ludwig Zenz