mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-20 05:13:59 +00:00
media: v4l: fwnode: Support default CSI-2 lane mapping for drivers
Most hardware doesn't support re-mapping of the CSI-2 lanes. Especially sensor drivers have a default number of lanes. Instead of requiring the caller (the driver) to provide such a unit mapping, provide one if no mapping is configured. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Tested-by: Steve Longerbeam <steve_longerbeam@mentor.com> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
c2475aeb12
commit
b4357d21d6
1 changed files with 46 additions and 14 deletions
|
@ -47,20 +47,35 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
|
||||||
enum v4l2_fwnode_bus_type bus_type)
|
enum v4l2_fwnode_bus_type bus_type)
|
||||||
{
|
{
|
||||||
struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2;
|
struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2;
|
||||||
bool have_clk_lane = false, have_lane_polarities = false;
|
bool have_clk_lane = false, have_data_lanes = false,
|
||||||
|
have_lane_polarities = false;
|
||||||
unsigned int flags = 0, lanes_used = 0;
|
unsigned int flags = 0, lanes_used = 0;
|
||||||
u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
|
u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
|
||||||
|
u32 clock_lane = 0;
|
||||||
unsigned int num_data_lanes = 0;
|
unsigned int num_data_lanes = 0;
|
||||||
|
bool use_default_lane_mapping = false;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u32 v;
|
u32 v;
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY) {
|
if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY) {
|
||||||
|
use_default_lane_mapping = true;
|
||||||
|
|
||||||
num_data_lanes = min_t(u32, bus->num_data_lanes,
|
num_data_lanes = min_t(u32, bus->num_data_lanes,
|
||||||
V4L2_FWNODE_CSI2_MAX_DATA_LANES);
|
V4L2_FWNODE_CSI2_MAX_DATA_LANES);
|
||||||
|
|
||||||
for (i = 0; i < num_data_lanes; i++)
|
clock_lane = bus->clock_lane;
|
||||||
|
if (clock_lane)
|
||||||
|
use_default_lane_mapping = false;
|
||||||
|
|
||||||
|
for (i = 0; i < num_data_lanes; i++) {
|
||||||
array[i] = bus->data_lanes[i];
|
array[i] = bus->data_lanes[i];
|
||||||
|
if (array[i])
|
||||||
|
use_default_lane_mapping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_default_lane_mapping)
|
||||||
|
pr_debug("using default lane mapping\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
|
rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
|
||||||
|
@ -70,15 +85,21 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
|
||||||
|
|
||||||
fwnode_property_read_u32_array(fwnode, "data-lanes", array,
|
fwnode_property_read_u32_array(fwnode, "data-lanes", array,
|
||||||
num_data_lanes);
|
num_data_lanes);
|
||||||
|
|
||||||
|
have_data_lanes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_data_lanes; i++) {
|
for (i = 0; i < num_data_lanes; i++) {
|
||||||
if (lanes_used & BIT(array[i]))
|
if (lanes_used & BIT(array[i])) {
|
||||||
pr_warn("duplicated lane %u in data-lanes\n",
|
if (have_data_lanes || !use_default_lane_mapping)
|
||||||
array[i]);
|
pr_warn("duplicated lane %u in data-lanes, using defaults\n",
|
||||||
|
array[i]);
|
||||||
|
use_default_lane_mapping = true;
|
||||||
|
}
|
||||||
lanes_used |= BIT(array[i]);
|
lanes_used |= BIT(array[i]);
|
||||||
|
|
||||||
pr_debug("lane %u position %u\n", i, array[i]);
|
if (have_data_lanes)
|
||||||
|
pr_debug("lane %u position %u\n", i, array[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
|
rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
|
||||||
|
@ -94,13 +115,16 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
|
if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
|
||||||
if (lanes_used & BIT(v))
|
clock_lane = v;
|
||||||
pr_warn("duplicated lane %u in clock-lanes\n", v);
|
|
||||||
lanes_used |= BIT(v);
|
|
||||||
|
|
||||||
bus->clock_lane = v;
|
|
||||||
have_clk_lane = true;
|
|
||||||
pr_debug("clock lane position %u\n", v);
|
pr_debug("clock lane position %u\n", v);
|
||||||
|
have_clk_lane = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lanes_used & BIT(clock_lane)) {
|
||||||
|
if (have_clk_lane || !use_default_lane_mapping)
|
||||||
|
pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
|
||||||
|
v);
|
||||||
|
use_default_lane_mapping = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fwnode_property_present(fwnode, "clock-noncontinuous")) {
|
if (fwnode_property_present(fwnode, "clock-noncontinuous")) {
|
||||||
|
@ -115,8 +139,16 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
|
||||||
bus->flags = flags;
|
bus->flags = flags;
|
||||||
vep->bus_type = V4L2_MBUS_CSI2_DPHY;
|
vep->bus_type = V4L2_MBUS_CSI2_DPHY;
|
||||||
bus->num_data_lanes = num_data_lanes;
|
bus->num_data_lanes = num_data_lanes;
|
||||||
for (i = 0; i < num_data_lanes; i++)
|
|
||||||
bus->data_lanes[i] = array[i];
|
if (use_default_lane_mapping) {
|
||||||
|
bus->clock_lane = 0;
|
||||||
|
for (i = 0; i < num_data_lanes; i++)
|
||||||
|
bus->data_lanes[i] = 1 + i;
|
||||||
|
} else {
|
||||||
|
bus->clock_lane = clock_lane;
|
||||||
|
for (i = 0; i < num_data_lanes; i++)
|
||||||
|
bus->data_lanes[i] = array[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (have_lane_polarities) {
|
if (have_lane_polarities) {
|
||||||
fwnode_property_read_u32_array(fwnode,
|
fwnode_property_read_u32_array(fwnode,
|
||||||
|
|
Loading…
Add table
Reference in a new issue