From patchwork Tue Mar 3 10:19:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Shih X-Patchwork-Id: 1248276 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=mediatek.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=mediatek.com header.i=@mediatek.com header.a=rsa-sha256 header.s=dk header.b=fStkvVGf; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48WtKW2yzpz9sPg for ; Tue, 3 Mar 2020 21:19:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728527AbgCCKT1 (ORCPT ); Tue, 3 Mar 2020 05:19:27 -0500 Received: from mailgw01.mediatek.com ([210.61.82.183]:8670 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726661AbgCCKT0 (ORCPT ); Tue, 3 Mar 2020 05:19:26 -0500 X-UUID: 117aaee898884524a57a71c695fb40cc-20200303 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=kNo7DFj3b9HktV/9EBruUcLqKxjTBFu6uKwuH9eM2VA=; b=fStkvVGfdODZUFXguzcaSao361mDB+EW3bBusAbnaUlGGE/VqKZLS5KuAaEyBY9TUxIXZXS5weqU0adXCsNkx6rOzkyQYQmMquvB2VF3631lmuQE71qIba/YVbK+YKby1XTp4ukN2F+CcXHcwjVWne3RcKqaERgSJw5JrlcgMCQ=; X-UUID: 117aaee898884524a57a71c695fb40cc-20200303 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 2000101293; Tue, 03 Mar 2020 18:19:20 +0800 Received: from mtkcas09.mediatek.inc (172.21.101.178) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Tue, 3 Mar 2020 18:18:18 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas09.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Tue, 3 Mar 2020 18:19:16 +0800 From: Sam Shih To: Thierry Reding , =?utf-8?q?Uwe_Kleine-K?= =?utf-8?b?w7ZuaWc=?= , Matthias Brugger CC: John Crispin , , , , , Sam Shih Subject: [PATCH v2 1/1] pwm: mediatek: add longer period support Date: Tue, 3 Mar 2020 18:19:15 +0800 Message-ID: <1583230755-25986-2-git-send-email-sam.shih@mediatek.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1583230755-25986-1-git-send-email-sam.shih@mediatek.com> References: <1583230755-25986-1-git-send-email-sam.shih@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org The pwm clock source could be divided by 1625 with PWM_CON BIT(3) setting in mediatek hardware. This patch add support for longer pwm period configuration, which allowing blinking LEDs via pwm interface. Signed-off-by: Sam Shih --- drivers/pwm/pwm-mediatek.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index b94e0d09c300..c64ecff6c550 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -121,8 +121,11 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); - u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH, - reg_thres = PWMTHRES; + /* The source clock is divided by 2^clkdiv or iff the clksel bit + * is set by (2^clkdiv*1625) + */ + u32 clkdiv = 0, clksel = 0, cnt_period, cnt_duty, + reg_width = PWMDWIDTH, reg_thres = PWMTHRES; u64 resolution; int ret; @@ -133,12 +136,30 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, /* Using resolution in picosecond gets accuracy higher */ resolution = (u64)NSEC_PER_SEC * 1000; + /* Calculate resolution based on current clock frequency */ do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm])); - + /* Using resolution to calculate cnt_period which represents + * the effective range of the PWM period counter + */ cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); while (cnt_period > 8191) { + /* Using clkdiv to reduce clock frequency and calculate + * new resolution based on new clock speed + */ resolution *= 2; clkdiv++; + if (clkdiv > PWM_CLK_DIV_MAX && !clksel) { + /* Using clksel to divide the pwm source clock by + * an additional 1625, and recalculate new clkdiv + * and resolution + */ + clksel = 1; + clkdiv = 0; + resolution = (u64)NSEC_PER_SEC * 1000 * 1625; + do_div(resolution, + clk_get_rate(pc->clk_pwms[pwm->hwpwm])); + } + /* Calculate cnt_period based on resolution */ cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); } @@ -158,8 +179,13 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, reg_thres = PWM45THRES_FIXUP; } + /* Calculate cnt_duty based on resolution */ cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution); - pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); + if (clksel) + pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | + clkdiv); + else + pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period); pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty);