Commit 276565ed authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

media: v4l: fwnode: Read lane inversion information despite lane numbering

Read the lane inversion independently of whether the "data-lanes" property
exists. This makes sense since the caller may pass the number of lanes as
the default configuration while the lane inversion configuration may still
be available in firmware.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Tested-by: default avatarSteve Longerbeam <steve_longerbeam@mentor.com>
Tested-by: default avatarJacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 175b18b8
...@@ -43,26 +43,31 @@ enum v4l2_fwnode_bus_type { ...@@ -43,26 +43,31 @@ enum v4l2_fwnode_bus_type {
}; };
static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
struct v4l2_fwnode_endpoint *vep) struct v4l2_fwnode_endpoint *vep,
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; bool have_clk_lane = false;
unsigned int flags = 0, lanes_used = 0; unsigned int flags = 0, lanes_used = 0;
u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
unsigned int num_data_lanes = 0;
unsigned int i; unsigned int i;
u32 v; u32 v;
int rval; int rval;
if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY)
num_data_lanes = min_t(u32, bus->num_data_lanes,
V4L2_FWNODE_CSI2_MAX_DATA_LANES);
rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
if (rval > 0) { if (rval > 0) {
u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES]; num_data_lanes =
bus->num_data_lanes =
min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval); min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval);
fwnode_property_read_u32_array(fwnode, "data-lanes", array, fwnode_property_read_u32_array(fwnode, "data-lanes", array,
bus->num_data_lanes); num_data_lanes);
for (i = 0; i < bus->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", pr_warn("duplicated lane %u in data-lanes\n",
array[i]); array[i]);
...@@ -71,22 +76,21 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, ...@@ -71,22 +76,21 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
bus->data_lanes[i] = array[i]; bus->data_lanes[i] = array[i];
pr_debug("lane %u position %u\n", i, array[i]); pr_debug("lane %u position %u\n", i, array[i]);
} }
}
rval = fwnode_property_read_u32_array(fwnode, rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
"lane-polarities", NULL,
0); 0);
if (rval > 0) { if (rval > 0) {
if (rval != 1 + bus->num_data_lanes /* clock+data */) { if (rval != 1 + num_data_lanes /* clock+data */) {
pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
1 + bus->num_data_lanes, rval); 1 + num_data_lanes, rval);
return -EINVAL; return -EINVAL;
} }
fwnode_property_read_u32_array(fwnode, fwnode_property_read_u32_array(fwnode, "lane-polarities", array,
"lane-polarities", array, 1 + num_data_lanes);
1 + bus->num_data_lanes);
for (i = 0; i < 1 + bus->num_data_lanes; i++) { for (i = 0; i < 1 + num_data_lanes; i++) {
bus->lane_polarities[i] = array[i]; bus->lane_polarities[i] = array[i];
pr_debug("lane %u polarity %sinverted", pr_debug("lane %u polarity %sinverted",
i, array[i] ? "" : "not "); i, array[i] ? "" : "not ");
...@@ -95,8 +99,6 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, ...@@ -95,8 +99,6 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
pr_debug("no lane polarities defined, assuming not inverted\n"); pr_debug("no lane polarities defined, assuming not inverted\n");
} }
}
if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
if (lanes_used & BIT(v)) if (lanes_used & BIT(v))
pr_warn("duplicated lane %u in clock-lanes\n", v); pr_warn("duplicated lane %u in clock-lanes\n", v);
...@@ -114,10 +116,11 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, ...@@ -114,10 +116,11 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
} }
if (lanes_used || have_clk_lane || if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY || lanes_used ||
(flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) { have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) {
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;
} }
return 0; return 0;
...@@ -268,7 +271,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, ...@@ -268,7 +271,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
switch (bus_type) { switch (bus_type) {
case V4L2_FWNODE_BUS_TYPE_GUESS: case V4L2_FWNODE_BUS_TYPE_GUESS:
rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
bus_type);
if (rval) if (rval)
return rval; return rval;
...@@ -284,7 +288,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, ...@@ -284,7 +288,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
break; break;
case V4L2_FWNODE_BUS_TYPE_CSI2_DPHY: case V4L2_FWNODE_BUS_TYPE_CSI2_DPHY:
vep->bus_type = V4L2_MBUS_CSI2_DPHY; vep->bus_type = V4L2_MBUS_CSI2_DPHY;
rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
bus_type);
if (rval) if (rval)
return rval; return rval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment