Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

platform/x86: Update swnode graph for amd isp4

Existing swnode graph format is specific to sensor device
and is causing conflicts when accessing standard property
variables outside the sensor driver.

To address this issue, enhanced swnode graph format with
dedicated nodes for i2c and isp devices, with sensor node
added as child to i2c node. This approach allows to have
standard property variables (ex: 'clock-frequency') with
values applicable for each of the devices (sensor, i2c and
isp).

ACPI device driver_data handle is also initialized with root
camera swnode to access the property variables in the graph
in isp and i2c drivers.

Signed-off-by: Pratap Nirujogi <pratap.nirujogi@amd.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20250618202958.3934822-1-pratap.nirujogi@amd.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Pratap Nirujogi and committed by
Ilpo Järvinen
e1af6f01 eb617dd2

+144 -37
+144 -37
drivers/platform/x86/amd/amd_isp4.c
··· 20 20 #define AMDISP_OV05C10_REMOTE_EP_NAME "ov05c10_isp_4_1_1" 21 21 #define AMD_ISP_PLAT_DRV_NAME "amd-isp4" 22 22 23 + static const struct software_node isp4_mipi1_endpoint_node; 24 + static const struct software_node ov05c10_endpoint_node; 25 + 23 26 /* 24 27 * AMD ISP platform info definition to initialize sensor 25 28 * specific platform configuration to prepare the amdisp ··· 45 42 struct mutex lock; /* protects i2c client creation */ 46 43 }; 47 44 48 - /* Top-level OV05C10 camera node property table */ 45 + /* Root AMD CAMERA SWNODE */ 46 + 47 + /* Root amd camera node definition */ 48 + static const struct software_node amd_camera_node = { 49 + .name = "amd_camera", 50 + }; 51 + 52 + /* ISP4 SWNODE */ 53 + 54 + /* ISP4 OV05C10 camera node definition */ 55 + static const struct software_node isp4_node = { 56 + .name = "isp4", 57 + .parent = &amd_camera_node, 58 + }; 59 + 60 + /* 61 + * ISP4 Ports node definition. No properties defined for 62 + * ports node. 63 + */ 64 + static const struct software_node isp4_ports = { 65 + .name = "ports", 66 + .parent = &isp4_node, 67 + }; 68 + 69 + /* 70 + * ISP4 Port node definition. No properties defined for 71 + * port node. 72 + */ 73 + static const struct software_node isp4_port_node = { 74 + .name = "port@0", 75 + .parent = &isp4_ports, 76 + }; 77 + 78 + /* 79 + * ISP4 MIPI1 remote endpoint points to OV05C10 endpoint 80 + * node. 81 + */ 82 + static const struct software_node_ref_args isp4_refs[] = { 83 + SOFTWARE_NODE_REFERENCE(&ov05c10_endpoint_node), 84 + }; 85 + 86 + /* ISP4 MIPI1 endpoint node properties table */ 87 + static const struct property_entry isp4_mipi1_endpoint_props[] = { 88 + PROPERTY_ENTRY_REF_ARRAY("remote-endpoint", isp4_refs), 89 + { } 90 + }; 91 + 92 + /* ISP4 MIPI1 endpoint node definition */ 93 + static const struct software_node isp4_mipi1_endpoint_node = { 94 + .name = "endpoint", 95 + .parent = &isp4_port_node, 96 + .properties = isp4_mipi1_endpoint_props, 97 + }; 98 + 99 + /* I2C1 SWNODE */ 100 + 101 + /* I2C1 camera node property table */ 102 + static const struct property_entry i2c1_camera_props[] = { 103 + PROPERTY_ENTRY_U32("clock-frequency", 1 * HZ_PER_MHZ), 104 + { } 105 + }; 106 + 107 + /* I2C1 camera node definition */ 108 + static const struct software_node i2c1_node = { 109 + .name = "i2c1", 110 + .parent = &amd_camera_node, 111 + .properties = i2c1_camera_props, 112 + }; 113 + 114 + /* I2C1 camera node property table */ 49 115 static const struct property_entry ov05c10_camera_props[] = { 50 116 PROPERTY_ENTRY_U32("clock-frequency", 24 * HZ_PER_MHZ), 51 117 { } 52 118 }; 53 119 54 - /* Root AMD ISP OV05C10 camera node definition */ 55 - static const struct software_node camera_node = { 120 + /* OV05C10 camera node definition */ 121 + static const struct software_node ov05c10_camera_node = { 56 122 .name = AMDISP_OV05C10_HID, 123 + .parent = &i2c1_node, 57 124 .properties = ov05c10_camera_props, 58 125 }; 59 126 60 127 /* 61 - * AMD ISP OV05C10 Ports node definition. No properties defined for 128 + * OV05C10 Ports node definition. No properties defined for 62 129 * ports node for OV05C10. 63 130 */ 64 - static const struct software_node ports = { 131 + static const struct software_node ov05c10_ports = { 65 132 .name = "ports", 66 - .parent = &camera_node, 133 + .parent = &ov05c10_camera_node, 67 134 }; 68 135 69 136 /* 70 - * AMD ISP OV05C10 Port node definition. No properties defined for 71 - * port node for OV05C10. 137 + * OV05C10 Port node definition. 72 138 */ 73 - static const struct software_node port_node = { 74 - .name = "port@", 75 - .parent = &ports, 139 + static const struct software_node ov05c10_port_node = { 140 + .name = "port@0", 141 + .parent = &ov05c10_ports, 76 142 }; 77 143 78 144 /* 79 - * Remote endpoint AMD ISP node definition. No properties defined for 80 - * remote endpoint node for OV05C10. 81 - */ 82 - static const struct software_node remote_ep_isp_node = { 83 - .name = AMDISP_OV05C10_REMOTE_EP_NAME, 84 - }; 85 - 86 - /* 87 - * Remote endpoint reference for isp node included in the 88 - * OV05C10 endpoint. 145 + * OV05C10 remote endpoint points to ISP4 MIPI1 endpoint 146 + * node. 89 147 */ 90 148 static const struct software_node_ref_args ov05c10_refs[] = { 91 - SOFTWARE_NODE_REFERENCE(&remote_ep_isp_node), 149 + SOFTWARE_NODE_REFERENCE(&isp4_mipi1_endpoint_node), 92 150 }; 93 151 94 152 /* OV05C10 supports one single link frequency */ 95 153 static const u64 ov05c10_link_freqs[] = { 96 - 925 * HZ_PER_MHZ, 154 + 900 * HZ_PER_MHZ, 97 155 }; 98 156 99 157 /* OV05C10 supports only 2-lane configuration */ ··· 174 110 { } 175 111 }; 176 112 177 - /* AMD ISP endpoint node definition */ 178 - static const struct software_node endpoint_node = { 113 + /* OV05C10 endpoint node definition */ 114 + static const struct software_node ov05c10_endpoint_node = { 179 115 .name = "endpoint", 180 - .parent = &port_node, 116 + .parent = &ov05c10_port_node, 181 117 .properties = ov05c10_endpoint_props, 182 118 }; 183 119 184 120 /* 185 - * AMD ISP swnode graph uses 5 nodes and also its relationship is 186 - * fixed to align with the structure that v4l2 expects for successful 187 - * endpoint fwnode parsing. 121 + * AMD Camera swnode graph uses 10 nodes and also its relationship is 122 + * fixed to align with the structure that v4l2 and i2c frameworks expects 123 + * for successful parsing of fwnodes and its properties with standard names. 188 124 * 189 125 * It is only the node property_entries that will vary for each platform 190 126 * supporting different sensor modules. 127 + * 128 + * AMD ISP4 SWNODE GRAPH Structure 129 + * 130 + * amd_camera { 131 + * isp4 { 132 + * ports { 133 + * port@0 { 134 + * isp4_mipi1_ep: endpoint { 135 + * remote-endpoint = &OMNI5C10_ep; 136 + * }; 137 + * }; 138 + * }; 139 + * }; 140 + * 141 + * i2c1 { 142 + * clock-frequency = 1 MHz; 143 + * OMNI5C10 { 144 + * clock-frequency = 24MHz; 145 + * ports { 146 + * port@0 { 147 + * OMNI5C10_ep: endpoint { 148 + * bus-type = 4; 149 + * data-lanes = <1 2>; 150 + * link-frequencies = 900MHz; 151 + * remote-endpoint = &isp4_mipi1; 152 + * }; 153 + * }; 154 + * }; 155 + * }; 156 + * }; 157 + * }; 158 + * 191 159 */ 192 - static const struct software_node *ov05c10_nodes[] = { 193 - &camera_node, 194 - &ports, 195 - &port_node, 196 - &endpoint_node, 197 - &remote_ep_isp_node, 160 + static const struct software_node *amd_isp4_nodes[] = { 161 + &amd_camera_node, 162 + &isp4_node, 163 + &isp4_ports, 164 + &isp4_port_node, 165 + &isp4_mipi1_endpoint_node, 166 + &i2c1_node, 167 + &ov05c10_camera_node, 168 + &ov05c10_ports, 169 + &ov05c10_port_node, 170 + &ov05c10_endpoint_node, 198 171 NULL 199 172 }; 200 173 ··· 241 140 .dev_name = "ov05c10", 242 141 I2C_BOARD_INFO("ov05c10", AMDISP_OV05C10_I2C_ADDR), 243 142 }, 244 - .swnodes = ov05c10_nodes, 143 + .swnodes = amd_isp4_nodes, 245 144 }; 246 145 247 146 static const struct acpi_device_id amdisp_sensor_ids[] = { ··· 333 232 if (ret) 334 233 return ERR_PTR(ret); 335 234 336 - isp4_platform->board_info.swnode = src->swnodes[0]; 235 + /* initialize ov05c10_camera_node */ 236 + isp4_platform->board_info.swnode = src->swnodes[6]; 337 237 338 238 return isp4_platform; 339 239 } ··· 359 257 { 360 258 const struct amdisp_platform_info *pinfo; 361 259 struct amdisp_platform *isp4_platform; 260 + struct acpi_device *adev; 362 261 int ret; 363 262 364 263 pinfo = device_get_match_data(&pdev->dev); ··· 376 273 ret = bus_register_notifier(&i2c_bus_type, &isp4_platform->i2c_nb); 377 274 if (ret) 378 275 goto error_unregister_sw_node; 276 + 277 + adev = ACPI_COMPANION(&pdev->dev); 278 + /* initialize root amd_camera_node */ 279 + adev->driver_data = (void *)pinfo->swnodes[0]; 379 280 380 281 /* check if adapter is already registered and create i2c client instance */ 381 282 i2c_for_each_dev(isp4_platform, try_to_instantiate_i2c_client);