From patchwork Fri Dec 22 11:16:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 757559 Received: from mail-lj1-f174.google.com (mail-lj1-f174.google.com [209.85.208.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F63B182C1 for ; Fri, 22 Dec 2023 11:17:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="neOxjvl7" Received: by mail-lj1-f174.google.com with SMTP id 38308e7fff4ca-2cc4029dc6eso20848901fa.1 for ; Fri, 22 Dec 2023 03:17:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1703243847; x=1703848647; 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=WLdzLfSEEVamw81pFt4PJ3qeYp2a8WvdFrJ9tUWJ7PY=; b=neOxjvl7SApVKcjiDSNvSRbxKF521OAdn4A/DPLOr513S/vRiYFQ6w/+F2MsWfRRDf oiCxjAAVThEyS94OcLJ6xlca9QuT7LrEoGnm4fltIuQgjTa7OVWHimBLxvscf7skg4bG nKSiHR2maMYlTi353vyAATJVNQDop0wsiBpP6qtY9i/Zfzm1D41euuQGgBsloR/iHqka 5ioqoVUDmfIAfziBXxq3V8Imuvvg8q3oP7a94Fp5Px1AO/U99Y87NZk+olIbU8ERN3O5 3ufHMp3culX8PX7NFLEDj2JSL/8aZ/hazBNJGvUwtUpuI+TZ3FI35yQ4Kjk8o7uim0rg GEdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703243847; x=1703848647; 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=WLdzLfSEEVamw81pFt4PJ3qeYp2a8WvdFrJ9tUWJ7PY=; b=pvy33Fss0IUewfxzxBUstlHubRtDoirf/DNWBRi76GDEbxBXsIO8bSjCvQkB317wpw gi7hBUqBCYTexGYrtUsbRqQox5VAgZ97kPkjR9Cqc04QrYb9e7fq6TZiedJwE4VIgYfy QphjK1Fffp/438X7teeSMR2Z1JvEVJsKFYA71mJpKHNhaPaGz8cUfmsz0O0teRodKX7c YkapLK+CzbYPM23oE8k3A4uGXqCA5sAs7sWIc0Tw3Hh9ReCxEYeil2IZKSxIRib6G4W/ Cl0qWHwdUYi2VfKJ4AP2PsCT9aKolt4VgJvNguGt3VHueNTqQJZ7yhrkhwdsoz+waC43 2xRQ== X-Gm-Message-State: AOJu0YzIr2HceuAuPw8IA12Ex3WgOOdT+zlbhjDgphrT2jeBpZ4F+U3q QFSeeYLndz3BYtqzgGM/t3J3y+VHWOMIEA== X-Google-Smtp-Source: AGHT+IHF8QykG43zRtMmkctjbVuKLYsW7rfsMx5OwczXw8lbMFtHQDq4/lLUPm3DgBYBmQiLWpgdfQ== X-Received: by 2002:a2e:2407:0:b0:2cc:2678:6d35 with SMTP id k7-20020a2e2407000000b002cc26786d35mr573523ljk.6.1703243846824; Fri, 22 Dec 2023 03:17:26 -0800 (PST) Received: from toaster.lan ([2a01:e0a:3c5:5fb1:c099:e596:3179:b0fa]) by smtp.googlemail.com with ESMTPSA id f8-20020adffcc8000000b003366b500047sm4054069wrs.50.2023.12.22.03.17.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Dec 2023 03:17:26 -0800 (PST) From: Jerome Brunet To: Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6n?= =?utf-8?q?ig?= , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Jerome Brunet , Kevin Hilman , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-pwm@vger.kernel.org, JunYi Zhao Subject: [PATCH v4 6/6] pwm: meson: add generic compatible for meson8 to sm1 Date: Fri, 22 Dec 2023 12:16:54 +0100 Message-ID: <20231222111658.832167-7-jbrunet@baylibre.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231222111658.832167-1-jbrunet@baylibre.com> References: <20231222111658.832167-1-jbrunet@baylibre.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Bot: notify Introduce a new compatible support in the Amlogic PWM driver. The PWM HW is actually the same for all SoCs supported so far. A specific compatible is needed only because the clock sources of the PWMs are hard-coded in the driver. It is better to have the clock source described in DT but this changes the bindings so a new compatible must be introduced. When all supported platform have migrated to the new compatible, support for the legacy ones may be removed from the driver. The addition of this new compatible makes the old ones obsolete, as described in the DT documentation. Adding a callback to setup the clock will also make it easier to add support for the new PWM HW found in a1, s4, c3 and t7 SoC families. Signed-off-by: Jerome Brunet --- drivers/pwm/pwm-meson.c | 240 ++++++++++++++++++++++++---------------- 1 file changed, 143 insertions(+), 97 deletions(-) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index fb113bc8da29..9c0a8a6e4f48 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -95,6 +95,7 @@ struct meson_pwm_channel { struct meson_pwm_data { const char * const *parent_names; + int (*channels_init)(struct device *dev); }; struct meson_pwm { @@ -333,108 +334,14 @@ static const struct pwm_ops meson_pwm_ops = { .get_state = meson_pwm_get_state, }; -static const char * const pwm_meson8b_parent_names[] = { - "xtal", NULL, "fclk_div4", "fclk_div3" -}; - -static const struct meson_pwm_data pwm_meson8b_data = { - .parent_names = pwm_meson8b_parent_names, -}; - -/* - * Only the 2 first inputs of the GXBB AO PWMs are valid - * The last 2 are grounded - */ -static const char * const pwm_gxbb_ao_parent_names[] = { - "xtal", "clk81", NULL, NULL, -}; - -static const struct meson_pwm_data pwm_gxbb_ao_data = { - .parent_names = pwm_gxbb_ao_parent_names, -}; - -static const char * const pwm_axg_ee_parent_names[] = { - "xtal", "fclk_div5", "fclk_div4", "fclk_div3" -}; - -static const struct meson_pwm_data pwm_axg_ee_data = { - .parent_names = pwm_axg_ee_parent_names, -}; - -static const char * const pwm_axg_ao_parent_names[] = { - "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" -}; - -static const struct meson_pwm_data pwm_axg_ao_data = { - .parent_names = pwm_axg_ao_parent_names, -}; - -static const char * const pwm_g12a_ao_ab_parent_names[] = { - "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" -}; - -static const struct meson_pwm_data pwm_g12a_ao_ab_data = { - .parent_names = pwm_g12a_ao_ab_parent_names, -}; - -static const char * const pwm_g12a_ao_cd_parent_names[] = { - "xtal", "g12a_ao_clk81", NULL, NULL, -}; - -static const struct meson_pwm_data pwm_g12a_ao_cd_data = { - .parent_names = pwm_g12a_ao_cd_parent_names, -}; - -static const struct of_device_id meson_pwm_matches[] = { - { - .compatible = "amlogic,meson8b-pwm", - .data = &pwm_meson8b_data - }, - { - .compatible = "amlogic,meson-gxbb-pwm", - .data = &pwm_meson8b_data - }, - { - .compatible = "amlogic,meson-gxbb-ao-pwm", - .data = &pwm_gxbb_ao_data - }, - { - .compatible = "amlogic,meson-axg-ee-pwm", - .data = &pwm_axg_ee_data - }, - { - .compatible = "amlogic,meson-axg-ao-pwm", - .data = &pwm_axg_ao_data - }, - { - .compatible = "amlogic,meson-g12a-ee-pwm", - .data = &pwm_meson8b_data - }, - { - .compatible = "amlogic,meson-g12a-ao-pwm-ab", - .data = &pwm_g12a_ao_ab_data - }, - { - .compatible = "amlogic,meson-g12a-ao-pwm-cd", - .data = &pwm_g12a_ao_cd_data - }, - {}, -}; -MODULE_DEVICE_TABLE(of, meson_pwm_matches); - -static int meson_pwm_init_channels(struct device *dev) +static int meson_pwm_init_clocks_legacy(struct device *dev, + struct clk_parent_data *mux_parent_data) { - struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {}; struct meson_pwm *meson = dev_get_drvdata(dev); unsigned int i; char name[255]; int err; - for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) { - mux_parent_data[i].index = -1; - mux_parent_data[i].name = meson->data->parent_names[i]; - } - for (i = 0; i < MESON_NUM_PWMS; i++) { struct meson_pwm_channel *channel = &meson->channels[i]; struct clk_parent_data div_parent = {}, gate_parent = {}; @@ -527,6 +434,145 @@ static int meson_pwm_init_channels(struct device *dev) return 0; } +static int meson_pwm_init_channels_legacy(struct device *dev) +{ + struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {}; + struct meson_pwm *meson = dev_get_drvdata(dev); + int i; + + dev_warn_once(dev, "using obsolete compatible, please consider updating dt\n"); + + for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) { + mux_parent_data[i].index = -1; + mux_parent_data[i].name = meson->data->parent_names[i]; + } + + return meson_pwm_init_clocks_legacy(dev, mux_parent_data); +} + +static int meson_pwm_init_channels_meson8b_v2(struct device *dev) +{ + struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {}; + int i; + + /* + * NOTE: Instead of relying on the hard coded names in the driver + * as the legacy version, this relies on DT to provide the list of + * clocks. + * For once, using input numbers actually makes more sense than names. + * Also DT requires clock-names to be explicitly ordered, so there is + * no point bothering with clock names in this case. + */ + for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) + mux_parent_data[i].index = i; + + return meson_pwm_init_clocks_legacy(dev, mux_parent_data); +} + +static const char * const pwm_meson8b_parent_names[] = { + "xtal", NULL, "fclk_div4", "fclk_div3" +}; + +static const struct meson_pwm_data pwm_meson8b_data = { + .parent_names = pwm_meson8b_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +/* + * Only the 2 first inputs of the GXBB AO PWMs are valid + * The last 2 are grounded + */ +static const char * const pwm_gxbb_ao_parent_names[] = { + "xtal", "clk81", NULL, NULL, +}; + +static const struct meson_pwm_data pwm_gxbb_ao_data = { + .parent_names = pwm_gxbb_ao_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +static const char * const pwm_axg_ee_parent_names[] = { + "xtal", "fclk_div5", "fclk_div4", "fclk_div3" +}; + +static const struct meson_pwm_data pwm_axg_ee_data = { + .parent_names = pwm_axg_ee_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +static const char * const pwm_axg_ao_parent_names[] = { + "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" +}; + +static const struct meson_pwm_data pwm_axg_ao_data = { + .parent_names = pwm_axg_ao_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +static const char * const pwm_g12a_ao_ab_parent_names[] = { + "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" +}; + +static const struct meson_pwm_data pwm_g12a_ao_ab_data = { + .parent_names = pwm_g12a_ao_ab_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +static const char * const pwm_g12a_ao_cd_parent_names[] = { + "xtal", "g12a_ao_clk81", NULL, NULL, +}; + +static const struct meson_pwm_data pwm_g12a_ao_cd_data = { + .parent_names = pwm_g12a_ao_cd_parent_names, + .channels_init = meson_pwm_init_channels_legacy, +}; + +static const struct meson_pwm_data pwm_meson8_v2_data = { + .channels_init = meson_pwm_init_channels_meson8b_v2, +}; + +static const struct of_device_id meson_pwm_matches[] = { + { + .compatible = "amlogic,meson8-pwm-v2", + .data = &pwm_meson8_v2_data + }, + /* The following compatibles are obsolete */ + { + .compatible = "amlogic,meson8b-pwm", + .data = &pwm_meson8b_data + }, + { + .compatible = "amlogic,meson-gxbb-pwm", + .data = &pwm_meson8b_data + }, + { + .compatible = "amlogic,meson-gxbb-ao-pwm", + .data = &pwm_gxbb_ao_data + }, + { + .compatible = "amlogic,meson-axg-ee-pwm", + .data = &pwm_axg_ee_data + }, + { + .compatible = "amlogic,meson-axg-ao-pwm", + .data = &pwm_axg_ao_data + }, + { + .compatible = "amlogic,meson-g12a-ee-pwm", + .data = &pwm_meson8b_data + }, + { + .compatible = "amlogic,meson-g12a-ao-pwm-ab", + .data = &pwm_g12a_ao_ab_data + }, + { + .compatible = "amlogic,meson-g12a-ao-pwm-cd", + .data = &pwm_g12a_ao_cd_data + }, + {}, +}; +MODULE_DEVICE_TABLE(of, meson_pwm_matches); + static int meson_pwm_probe(struct platform_device *pdev) { struct meson_pwm *meson; @@ -554,7 +600,7 @@ static int meson_pwm_probe(struct platform_device *pdev) meson->data = of_device_get_match_data(&pdev->dev); - err = meson_pwm_init_channels(&pdev->dev); + err = meson->data->channels_init(&pdev->dev); if (err < 0) return err;