From patchwork Thu Nov 9 10:06:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 163321 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp332758vqs; Thu, 9 Nov 2023 02:08:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IFi7zfY+MckibgJteWzP1XzPjruye1xadJ62orFqOM0jGCASITe39EndYAyFXa7kNR4pHCZ X-Received: by 2002:a05:6a21:7189:b0:17b:e0a3:f6f4 with SMTP id wq9-20020a056a21718900b0017be0a3f6f4mr4845854pzb.25.1699524489061; Thu, 09 Nov 2023 02:08:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699524489; cv=none; d=google.com; s=arc-20160816; b=L/T4DqN8IdXs0xVPSNkyObdOFwVdhrM3RyuXRykUwfBSwaIl8vH131Ir7WRsRPCr0s l+TPBwbFxK/yJlziAcDRzn+1jt3KU0L5mWXmScmw99snu00gpFId8rQHulqIs1HC3Nc6 iaHOdeTD33Q6ziIC19i79VvJzS//cWzQo7o3QBUrJx50Y+ixNo75xm8Gzphw5NWUy+nH gX7BXXjz8Boz3N7OFjBZRegrdQRwdaV9YqX3NOhKMltX5ACRwKHx1XYU73gFgSmRDAJe 0pnUS5b02Aikk4QvuT1bKCucft6l9S3Gi2svYnhn8d32n0KtziExbZsZQk67AnELsmM+ Dsbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Rs4qbwNofKphTE2zreJeFqCc6xRNAsKGF5LoBHdl0a8=; fh=9RjyB+hDNs618LdaNPm846thAWpv+UOF4Pqs3eQuhzI=; b=jO/m9Im01867ZInfEOz1zc132mtLS8uhn9+rzfuz6llBCb8kJY8mD3mRZYhYLSc8Y9 LzIZQX6HagKF4H3oW7dDMd3QvUPgx5v/uPD36sgSdeo7XRlyarQuWbCG35kEe8zann1/ /pJD9qAqLHei5tJXhPKHelUIvkNtrfwpEVVZZ2d01GCyJ9Yb8CqngOiNTS6ujM4SA+/W iBtnlx1AWVYm3PPlBJHftRiITjjZ5qs5abWG8mzlWVbU9Yt5YgOImHJ7u4CVbotoMQw+ n/WsBaDVRzb3WF55yG3FoDUVX5s9jnYszEIyrwtK+FlcS2OssAZ/wGNZX6oeQS9dwtDT bITg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=HAkuhHb7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id ob18-20020a17090b391200b002775999122csi1448035pjb.141.2023.11.09.02.08.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 02:08:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=HAkuhHb7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 33BA18258997; Thu, 9 Nov 2023 02:08:00 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234334AbjKIKH3 (ORCPT + 32 others); Thu, 9 Nov 2023 05:07:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233290AbjKIKHG (ORCPT ); Thu, 9 Nov 2023 05:07:06 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 783CD30E1 for ; Thu, 9 Nov 2023 02:07:04 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id 41be03b00d2f7-5b856d73a12so566654a12.1 for ; Thu, 09 Nov 2023 02:07:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1699524424; x=1700129224; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Rs4qbwNofKphTE2zreJeFqCc6xRNAsKGF5LoBHdl0a8=; b=HAkuhHb7SzSz6OhGNf394Dui6jFOjbDVL3coBmNzq37xaektQl4rJtUPvTlaBeB42p q+As9HodIdDYp7KbqaNKRJTu1ASdCL5Fs1DdUMHs5q/gYAUtIuu2QVd5jVlYsoRlPPyL fpUw1CLXQhgPD3R7s6HFUjMFYsN+RuzDmDWk0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699524424; x=1700129224; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Rs4qbwNofKphTE2zreJeFqCc6xRNAsKGF5LoBHdl0a8=; b=wrLuduWSMbjbnZ5qsOQzOWsANM4tzrNDtVunWj7s3jm1hn/vlqrqWF+xgIyolI8urA SbeUK6rFjI2tM9BoykjrC3arEZWhb0kD120QMAPXj2USW4iI+ohp+m5fZ9db507Bmq2P Fkzr9XVj1w9kiICmCBsEgKs/uXTmvDFJwUYcTdLzup0onn0BdBQ0nLWxuETi6mbyqWWV YBNL340cLqM1Kmo1H9dIQidJm5bencB4ZIot/NG8pCmeZcGyTlDkYnv6FoL/1XiKk8TL bUSp161siLhtdJ+w0JUdbAgAKMMQ66CVaFg4p5VYENrMrrPuns5ColtHPdfRajOZNxLQ VQtg== X-Gm-Message-State: AOJu0YzpjaitFS+vj5FfL1Wxq3UbTZEHx5GlH3zXE2lcIdYxU60Yxx6C AtZzrvT5HXhINVe6pkFIhllEKQ== X-Received: by 2002:a17:902:f807:b0:1c9:b2c1:139c with SMTP id ix7-20020a170902f80700b001c9b2c1139cmr4180478plb.62.1699524423943; Thu, 09 Nov 2023 02:07:03 -0800 (PST) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:6f57:d4c:468c:5daf]) by smtp.gmail.com with ESMTPSA id c13-20020a170902d48d00b001c60ba709b7sm3127511plg.125.2023.11.09.02.06.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 02:07:03 -0800 (PST) From: Chen-Yu Tsai To: Rob Herring , Frank Rowand , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno Cc: Hsin-Yi Wang , Dmitry Torokhov , andriy.shevchenko@linux.intel.com, Jiri Kosina , linus.walleij@linaro.org, broonie@kernel.org, gregkh@linuxfoundation.org, hdegoede@redhat.com, james.clark@arm.com, james@equiv.tech, keescook@chromium.org, petr.tesarik.ext@huawei.com, rafael@kernel.org, tglx@linutronix.de, Jeff LaBundy , linux-input@vger.kernel.org, Chen-Yu Tsai , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, Douglas Anderson , Johan Hovold Subject: [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection Date: Thu, 9 Nov 2023 18:06:02 +0800 Message-ID: <20231109100606.1245545-6-wenst@chromium.org> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog In-Reply-To: <20231109100606.1245545-1-wenst@chromium.org> References: <20231109100606.1245545-1-wenst@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Thu, 09 Nov 2023 02:08:00 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782080590623997770 X-GMAIL-MSGID: 1782080590623997770 In cases where the same Chromebook model is manufactured with different components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad / touchscreens with conflicting addresses), a different SKU ID is allocated to each specific combination. This SKU ID is exported by the bootloader into the device tree, and can be used to "discover" which combination is present on the current machine. This change adds a hardware prober that will match the SKU ID against a provided table, and enable the component for the matched entry based on the given compatible string. In the MIPI DSI panel and MIPI CSI camera sensor cases which have OF graphs, it will also update the remote endpoint to point to the enabled component. This assumes a single endpoint only. This will provide a path to reducing the number of Chromebook device trees. Signed-off-by: Chen-Yu Tsai --- drivers/of/hw_prober.c | 160 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c index 442da6eff896..4345e5aed6d8 100644 --- a/drivers/of/hw_prober.c +++ b/drivers/of/hw_prober.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #define DRV_NAME "hw_prober" @@ -108,9 +109,168 @@ static int i2c_component_prober(struct platform_device *pdev, const void *data) return ret; } +static int cros_get_coreboot_sku_id(struct device *dev, u32 *sku_id) +{ + struct device_node *node = NULL; + int ret; + + node = of_find_node_by_path("/firmware/coreboot"); + if (!node) + return dev_err_probe(dev, -EINVAL, "Cannot find coreboot firmware node\n"); + + ret = of_property_read_u32(node, "sku-id", sku_id); + if (ret) + dev_err_probe(dev, ret, "Cannot get SKU ID\n"); + + of_node_put(node); + return ret; +} + +struct cros_sku_option { + u32 sku_id_val; + u32 sku_id_mask; + const char *compatible; +}; + +struct cros_sku_component_data { + const struct cros_sku_option *options; + int num_options; +}; + +/* + * cros_sku_component_selector - Selectively enable a component based on SKU ID + * + * Based on the list of component options and SKU ID read back from the device + * tree, enable the matching component. Also update the OF graph if it exists, + * so that the enabled component's remote endpoint correctly points to it. This + * assumes a single local endpoint, which should be the case for panels and + * camera sensors. + */ +static int cros_sku_component_selector(struct platform_device *pdev, const void *data) +{ + const struct cros_sku_component_data *pdata = data; + const char *compatible; + struct device_node *node = NULL, *endpoint = NULL, *remote = NULL; + struct property *status_prop = NULL, *endpoint_prop = NULL; + struct of_changeset *ocs = NULL; + __be32 *val = NULL; + int ret, i; + u32 sku_id; + + if (!data) + return dev_err_probe(&pdev->dev, -EINVAL, "No data given\n"); + + ret = cros_get_coreboot_sku_id(&pdev->dev, &sku_id); + if (ret) + return ret; + + for (i = 0; i < pdata->num_options; i++) + if ((sku_id & pdata->options[i].sku_id_mask) == pdata->options[i].sku_id_val) { + compatible = pdata->options->compatible; + break; + } + + if (i == pdata->num_options) + return dev_err_probe(&pdev->dev, -EINVAL, "Unknown SKU ID: 0x%x\n", sku_id); + + node = of_find_compatible_node(NULL, NULL, compatible); + if (!node) + return dev_err_probe(&pdev->dev, -ENODEV, "Cannot find matching device node\n"); + + /* device node not marked as fail; don't mess with the device tree */ + if (!of_device_is_fail(node)) + goto err_free; + + dev_info(&pdev->dev, "Enabling %pOF for SKU 0x%x\n", node, sku_id); + + ret = -ENOMEM; + ocs = kzalloc(sizeof(*ocs), GFP_KERNEL); + if (!ocs) + goto err_free; + + status_prop = kzalloc(sizeof(*status_prop), GFP_KERNEL); + if (!status_prop) + goto err_free; + + status_prop->name = "status"; + status_prop->length = 5; + status_prop->value = "okay"; + + /* Create changeset to apply DT changes atomically */ + of_changeset_init(ocs); + + if (of_graph_is_present(node)) { + ret = -EINVAL; + + /* This currently assumes a single port on the component. */ + endpoint = of_graph_get_next_endpoint(node, NULL); + if (!endpoint) { + dev_err(&pdev->dev, "No endpoint found for %pOF\n", node); + goto err_destroy_ocs; + } + + remote = of_graph_get_remote_endpoint(endpoint); + if (!remote) { + dev_err(&pdev->dev, "No remote endpoint node found for %pOF\n", endpoint); + goto err_destroy_ocs; + } + + endpoint_prop = kzalloc(sizeof(*endpoint_prop), GFP_KERNEL); + if (!endpoint_prop) + goto err_destroy_ocs; + + val = kzalloc(sizeof(*val), GFP_KERNEL); + if (!val) + goto err_destroy_ocs; + + *val = cpu_to_be32(endpoint->phandle); + endpoint_prop->name = "remote-endpoint"; + endpoint_prop->length = sizeof(*val); + endpoint_prop->value = val; + + ret = of_changeset_update_property(ocs, node, endpoint_prop); + if (ret) + goto err_destroy_ocs; + } + + ret = of_changeset_update_property(ocs, node, status_prop); + if (ret) + goto err_destroy_ocs; + ret = of_changeset_apply(ocs); + if (ret) + goto err_destroy_ocs; + + of_node_put(node); + + return 0; + +err_destroy_ocs: + of_node_put(remote); + of_node_put(endpoint); + kfree(val); + kfree(endpoint_prop); + of_changeset_destroy(ocs); +err_free: + kfree(ocs); + kfree(status_prop); + of_node_put(node); + return ret; +} + +static const struct cros_sku_option cros_krane_panel_options[] = { + { .sku_id_val = 0x00, .sku_id_mask = 0xf0, .compatible = "auo,kd101n80-45na" }, + { .sku_id_val = 0xb0, .sku_id_mask = 0xf0, .compatible = "boe,tv101wum-nl6" }, +}; + +static const struct cros_sku_component_data cros_krane_panel_data = { + .options = cros_krane_panel_options, + .num_options = ARRAY_SIZE(cros_krane_panel_options), +}; + static const struct hw_prober_entry hw_prober_platforms[] = { { .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" }, { .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" }, + { .compatible = "google,krane", .prober = cros_sku_component_selector, .data = &cros_krane_panel_data }, }; static int hw_prober_probe(struct platform_device *pdev)