From 1ec5de421d6f4b7fac4cf62fc95901763cf42163 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 4 Jun 2025 17:02:58 +0300 Subject: [PATCH 1/5] rpi5-gmsl: make deserializer TPG pad/stream dynamic --- utils/cam/cam-configs/rpi5-gmsl.py | 43 +++++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/utils/cam/cam-configs/rpi5-gmsl.py b/utils/cam/cam-configs/rpi5-gmsl.py index 54e2168..8338f33 100644 --- a/utils/cam/cam-configs/rpi5-gmsl.py +++ b/utils/cam/cam-configs/rpi5-gmsl.py @@ -188,7 +188,10 @@ def gen_imx219_meta(des_ent, des_src_pad, ch_index, cameras, port): ], } -def gen_des_tpg(des_ent, des_src_pad, ch_index): +def gen_des_tpg(des_ent, des_src_pad, deser_tpg_pad, ch_index): + assert deser_tpg_pad is not None + + tpg_stream = 16 return { 'media': MEDIA_DEVICE_NAME, @@ -197,11 +200,11 @@ def gen_des_tpg(des_ent, des_src_pad, ch_index): { 'entity': des_ent, 'routing': [ - { 'src': (8, 0), 'dst': (des_src_pad, 0) }, + { 'src': (deser_tpg_pad, 0), 'dst': (des_src_pad, tpg_stream) }, ], 'pads': [ - { 'pad': (8, 0), 'fmt': mbus_fmt_tpg }, - { 'pad': (des_src_pad, 0), 'fmt': mbus_fmt_tpg }, + { 'pad': (deser_tpg_pad, 0), 'fmt': mbus_fmt_tpg }, + { 'pad': (des_src_pad, tpg_stream), 'fmt': mbus_fmt_tpg }, ], }, @@ -209,10 +212,10 @@ def gen_des_tpg(des_ent, des_src_pad, ch_index): { 'entity': CSI2_NAME, 'routing': [ - { 'src': (0, 0), 'dst': (1 + ch_index, 0) }, + { 'src': (0, tpg_stream), 'dst': (1 + ch_index, 0) }, ], 'pads': [ - { 'pad': (0, 0), 'fmt': mbus_fmt_tpg }, + { 'pad': (0, tpg_stream), 'fmt': mbus_fmt_tpg }, { 'pad': (1 + ch_index, 0), 'fmt': mbus_fmt_tpg }, ], }, @@ -234,6 +237,8 @@ def gen_des_tpg(des_ent, des_src_pad, ch_index): def gen_ser_tpg(des_ent, des_src_pad, ch_index, cameras, port): ser_ent = cameras[port][0] + ser_tpg_stream = 2 + des_tpg_stream = port + 8 return { 'media': MEDIA_DEVICE_NAME, @@ -242,22 +247,22 @@ def gen_ser_tpg(des_ent, des_src_pad, ch_index, cameras, port): { 'entity': ser_ent, 'routing': [ - { 'src': (2, 0), 'dst': (1, 0) }, + { 'src': (2, 0), 'dst': (1, ser_tpg_stream) }, ], 'pads': [ { 'pad': (2, 0), 'fmt': mbus_fmt_tpg }, - { 'pad': (1, 0), 'fmt': mbus_fmt_tpg }, + { 'pad': (1, ser_tpg_stream), 'fmt': mbus_fmt_tpg }, ], }, # Deserializer { 'entity': des_ent, 'routing': [ - { 'src': (port, 0), 'dst': (des_src_pad, port) }, + { 'src': (port, ser_tpg_stream), 'dst': (des_src_pad, des_tpg_stream) }, ], 'pads': [ - { 'pad': (port, 0), 'fmt': mbus_fmt_tpg }, - { 'pad': (des_src_pad, port), 'fmt': mbus_fmt_tpg }, + { 'pad': (port, ser_tpg_stream), 'fmt': mbus_fmt_tpg }, + { 'pad': (des_src_pad, des_tpg_stream), 'fmt': mbus_fmt_tpg }, ], }, @@ -265,10 +270,10 @@ def gen_ser_tpg(des_ent, des_src_pad, ch_index, cameras, port): { 'entity': CSI2_NAME, 'routing': [ - { 'src': (0, port), 'dst': (1 + ch_index, 0) }, + { 'src': (0, des_tpg_stream), 'dst': (1 + ch_index, 0) }, ], 'pads': [ - { 'pad': (0, port), 'fmt': mbus_fmt_tpg }, + { 'pad': (0, des_tpg_stream), 'fmt': mbus_fmt_tpg }, { 'pad': (1 + ch_index, 0), 'fmt': mbus_fmt_tpg }, ], }, @@ -296,6 +301,7 @@ def find_devices(mdev_name, deser_regex): assert deser deser_src_pad = None + deser_tpg_pad = None for p in deser.pads: if p.is_source and len(p.links) == 1 and \ p.links[0].sink.entity.name == CSI2_NAME: @@ -303,6 +309,11 @@ def find_devices(mdev_name, deser_regex): break assert deser_src_pad is not None + for p in deser.pads: + if p.is_internal: + deser_tpg_pad = p.index + break + cameras = {} for p in deser.pads: @@ -319,10 +330,10 @@ def find_devices(mdev_name, deser_regex): cameras[p.index] = (ser.name, sensor.name) - return deser.name, deser_src_pad, cameras + return deser.name, deser_src_pad, deser_tpg_pad, cameras def get_configs(config_names): - des_name, des_src_pad, cameras = find_devices(MEDIA_DEVICE_NAME, DESER_REGEX) + des_name, des_src_pad, deser_tpg_pad, cameras = find_devices(MEDIA_DEVICE_NAME, DESER_REGEX) cfgs = [] ch_index = 0 @@ -351,7 +362,7 @@ def get_configs(config_names): if 'des-tpg' in config_names: config_names.remove('des-tpg') - cfg = gen_des_tpg(des_name, des_src_pad, ch_index) + cfg = gen_des_tpg(des_name, des_src_pad, deser_tpg_pad, ch_index) cfgs.append(cfg) ch_index += 1 From f938def10a279680983522f0ca7ca73407563eac Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 6 Jun 2025 00:51:36 +0300 Subject: [PATCH 2/5] rpi5-gmsl: fix entity not using incremental channel index --- utils/cam/cam-configs/rpi5-gmsl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/cam/cam-configs/rpi5-gmsl.py b/utils/cam/cam-configs/rpi5-gmsl.py index 8338f33..865dc4b 100644 --- a/utils/cam/cam-configs/rpi5-gmsl.py +++ b/utils/cam/cam-configs/rpi5-gmsl.py @@ -281,7 +281,7 @@ def gen_ser_tpg(des_ent, des_src_pad, ch_index, cameras, port): 'devices': [ { - 'entity': f'rp1-cfe-csi2-ch{port}', + 'entity': f'rp1-cfe-csi2-ch{ch_index}', 'fmt': fmt_tpg, }, ], From a9b3df54c0ce068b5dc000edaabaa72762b6bfa6 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Wed, 18 Jun 2025 01:34:01 +0300 Subject: [PATCH 3/5] rpi5-gmsl: allow serializers to have unconnected cameras --- utils/cam/cam-configs/rpi5-gmsl.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/utils/cam/cam-configs/rpi5-gmsl.py b/utils/cam/cam-configs/rpi5-gmsl.py index 865dc4b..35012ca 100644 --- a/utils/cam/cam-configs/rpi5-gmsl.py +++ b/utils/cam/cam-configs/rpi5-gmsl.py @@ -43,6 +43,7 @@ def gen_imx219_pixel(des_ent, des_src_pad, ch_index, cameras, port): sensor_ent = cameras[port][1] ser_ent = cameras[port][0] + assert sensor_ent is not None return { 'media': MEDIA_DEVICE_NAME, @@ -117,6 +118,7 @@ def gen_imx219_pixel(des_ent, des_src_pad, ch_index, cameras, port): def gen_imx219_meta(des_ent, des_src_pad, ch_index, cameras, port): sensor_ent = cameras[port][1] ser_ent = cameras[port][0] + assert sensor_ent is not None return { 'media': MEDIA_DEVICE_NAME, @@ -326,9 +328,12 @@ def find_devices(mdev_name, deser_regex): assert len(p.links) == 1 ser = p.links[0].source.entity - sensor = ser.pads[0].links[0].source.entity + sensor_name = None + if len(ser.pads[0].links) == 1: + sensor = ser.pads[0].links[0].source.entity + sensor_name = sensor.name - cameras[p.index] = (ser.name, sensor.name) + cameras[p.index] = (ser.name, sensor_name) return deser.name, deser_src_pad, deser_tpg_pad, cameras From 6a4993ebccb30189b003c6da9e165bdfd5abb30d Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 5 Jun 2025 20:16:48 +0300 Subject: [PATCH 4/5] rpi5-gmsl: switch TPG to 1080p --- utils/cam/cam-configs/rpi5-gmsl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/cam/cam-configs/rpi5-gmsl.py b/utils/cam/cam-configs/rpi5-gmsl.py index 35012ca..db8ad43 100644 --- a/utils/cam/cam-configs/rpi5-gmsl.py +++ b/utils/cam/cam-configs/rpi5-gmsl.py @@ -36,8 +36,8 @@ # TPG -mbus_fmt_tpg = (640, 480, v4l2.BusFormat.RGB888_1X24) -fmt_tpg = (640, 480, v4l2.PixelFormats.BGR888) +mbus_fmt_tpg = (1920, 1080, v4l2.BusFormat.RGB888_1X24) +fmt_tpg = (1920, 1080, v4l2.PixelFormats.BGR888) def gen_imx219_pixel(des_ent, des_src_pad, ch_index, cameras, port): From 4aa8d73a1d02f99fb44a4422d7b642fb28aa0fa5 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 18 Jul 2025 17:39:08 +0300 Subject: [PATCH 5/5] rpi5-gmsl: set empty routing for unused serializers --- utils/cam/cam-configs/rpi5-gmsl.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/utils/cam/cam-configs/rpi5-gmsl.py b/utils/cam/cam-configs/rpi5-gmsl.py index db8ad43..65b928a 100644 --- a/utils/cam/cam-configs/rpi5-gmsl.py +++ b/utils/cam/cam-configs/rpi5-gmsl.py @@ -295,6 +295,21 @@ def gen_ser_tpg(des_ent, des_src_pad, ch_index, cameras, port): ], } +def gen_empty_ser(cameras, port): + ser_ent = cameras[port][0] + + return { + 'media': MEDIA_DEVICE_NAME, + + 'subdevs': [ + # Serializer + { + 'entity': ser_ent, + 'routing': [], + }, + ], + } + # Find serializers and sensors connected to the deserializer def find_devices(mdev_name, deser_regex): md = v4l2.MediaDevice(*mdev_name) @@ -346,24 +361,32 @@ def get_configs(config_names): cam = f'cam{i}' cam_meta = f'cam{i}-meta' ser_tpg = f'ser{i}-tpg' + ser_in_use = False if cam in config_names: config_names.remove(cam) cfg = gen_imx219_pixel(des_name, des_src_pad, ch_index, cameras, i) cfgs.append(cfg) ch_index += 1 + ser_in_use = True if cam_meta in config_names: config_names.remove(cam_meta) cfg = gen_imx219_meta(des_name, des_src_pad, ch_index, cameras, i) cfgs.append(cfg) ch_index += 1 + ser_in_use = True if ser_tpg in config_names: cfg = gen_ser_tpg(des_name, des_src_pad, ch_index, cameras, i) config_names.remove(ser_tpg) cfgs.append(cfg) ch_index += 1 + ser_in_use = True + + if not ser_in_use: + cfg = gen_empty_ser(cameras, i) + cfgs.append(cfg) if 'des-tpg' in config_names: config_names.remove('des-tpg')