Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH] ARM: UNWINDER_FRAME_POINTER implementation for Clang
From: Dave Martin @ 2019-08-07 10:29 UTC (permalink / raw)
  To: Nathan Huckleberry
  Cc: Tri Vo, linux, linux-kernel, clang-built-linux, Robin Murphy,
	linux-arm-kernel
In-Reply-To: <CAJkfWY5EL+MyRzSfcfJF2H8WoX73FEO0bOrwcoR4c4ekvaWvOQ@mail.gmail.com>

On Tue, Aug 06, 2019 at 02:29:16PM -0700, Nathan Huckleberry wrote:
> I'm not sure that we should disable a broken feature instead of
> attempting a fix.
> 
> CONFIG_FUNCTION_GRAPH_TRACER is dependent on CONFIG_FRAME_POINTER and
> there have been reports by MediaTek that the frame pointer unwinder is
> faster in some cases.

Fair enough, just wanted to be sure we weren't doing something pointless.

[...]

Cheers
---Dave

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 1/5] firmware: arm_scmi: Add discovery of SCMI v2.0 performance fastchannels
From: Sudeep Holla @ 2019-08-07 10:28 UTC (permalink / raw)
  To: Peng Fan
  Cc: aidapala@qti.qualcomm.com, Etienne Carriere, Souvik Chakravarty,
	wesleys@xilinx.com, Ionela Voinescu, linux-kernel@vger.kernel.org,
	Saeed Nowshadi, Quentin Perret, Bo Zhang, Felix Burton,
	Jim Quinlan, Chris Redpath, pajay@qti.qualcomm.com, Gaku Inami,
	Volodymyr Babchuk, linux-arm-kernel@lists.infradead.org
In-Reply-To: <AM0PR04MB4481BA101A13A0E45DA50E9088D40@AM0PR04MB4481.eurprd04.prod.outlook.com>

On Wed, Aug 07, 2019 at 09:23:41AM +0000, Peng Fan wrote:
> > Subject: [PATCH v2 1/5] firmware: arm_scmi: Add discovery of SCMI v2.0
> > performance fastchannels
> >
> > SCMI v2.0 adds support for "FastChannel", a lightweight unidirectional
> > channel that is dedicated to a single SCMI message type for controlling a
> > specific platform resource. They do not use a message header as they are
> > specialized for a single message.
> >
> > Only PERFORMANCE_LIMITS_{SET,GET} and
> > PERFORMANCE_LEVEL_{SET,GET} commands are supported over
> > fastchannels. As they are optional, they need to be discovered by
> > PERFORMANCE_DESCRIBE_FASTCHANNEL command.
> > Further {LIMIT,LEVEL}_SET commands can have optional doorbell support.
> >
> > Add support for discovery of these fastchannels.
> >
> > Cc: Ionela Voinescu <Ionela.Voinescu@arm.com>
> > Cc: Chris Redpath <Chris.Redpath@arm.com>
> > Cc: Quentin Perret <Quentin.Perret@arm.com>
> > Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> > ---
> >  drivers/firmware/arm_scmi/perf.c | 153
> > ++++++++++++++++++++++++++++++-
> >  1 file changed, 149 insertions(+), 4 deletions(-)
> >

[...]

>
> Reviewed-by: Peng Fan <peng.fan@nxp.com>
>

Thanks for the review.

--
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 3/5] dt-bindings: arm: Extend SCMI to support new reset protocol
From: Sudeep Holla @ 2019-08-07 10:18 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Mark Rutland, devicetree, Peng Fan, Etienne Carriere,
	Souvik Chakravarty, wesleys, aidapala, linux-kernel, Rob Herring,
	Saeed Nowshadi, Bo Zhang, Felix Burton, Jim Quinlan, pajay,
	Gaku Inami, Volodymyr Babchuk, linux-arm-kernel
In-Reply-To: <1565166410.5048.5.camel@pengutronix.de>

On Wed, Aug 07, 2019 at 10:26:50AM +0200, Philipp Zabel wrote:
> On Tue, 2019-08-06 at 18:02 +0100, Sudeep Holla wrote:
> > SCMIv2.0 adds a new Reset Management Protocol to manage various reset
> > states a given device or domain can enter. Extend the existing SCMI
> > bindings to add reset protocol support by re-using the reset bindings
> > for bothe reset providers and consumers.
>           ^
> typo
>

Thanks, fixed now.

--
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v4 0/3] DCMI bridge support
From: Hans Verkuil @ 2019-08-07 10:15 UTC (permalink / raw)
  To: Hugues Fruchet, Alexandre Torgue, Mauro Carvalho Chehab,
	Sakari Ailus
  Cc: Mickael GUENE, linux-kernel, Philippe CORNU, Yannick Fertre,
	Benjamin Gaignard, linux-stm32, linux-arm-kernel, linux-media
In-Reply-To: <1564577783-18627-1-git-send-email-hugues.fruchet@st.com>

Hi Hugues,

Can you provide the output of the most recent v4l2-compliance?

Use 'v4l2-compliance -s'.

Also, just to confirm, with this v4 there are no /dev/mediaX or
/dev/v4l-subdevX devices created anymore, right?

This v4 looks good to me, I just want to have these final checks
done.

Regards,

	Hans

On 7/31/19 2:56 PM, Hugues Fruchet wrote:
> This patch serie allows to connect non-parallel camera sensor to
> DCMI thanks to a bridge connected in between such as STMIPID02 [1].
> 
> Media controller support is introduced first, then support of
> several sub-devices within pipeline with dynamic linking
> between them.
> In order to keep backward compatibility with applications
> relying on V4L2 interface only, format set on video node
> is propagated to all sub-devices connected to camera interface.
> 
> [1] https://www.spinics.net/lists/devicetree/msg278002.html
> 
> ===========
> = history =
> ===========
> version 4:
>   - Also drop subdev nodes registry as suggested by Hans:
>     https://www.spinics.net/lists/arm-kernel/msg743375.html
> 
> version 3:
>   - Drop media device registry to not expose media controller
>     interface to userspace as per Laurent' suggestion:
>     https://www.spinics.net/lists/linux-media/msg153417.html
>   - Prefer "source" instead of "sensor" and keep it in 
>     dcmi_graph_entity struct, move asd as first member
>     of struct as per Sakari' suggestion:
>     https://www.spinics.net/lists/linux-media/msg153119.html
>   - Drop dcmi_graph_deinit() as per Sakari' suggestion:
>     https://www.spinics.net/lists/linux-media/msg153417.html
> 
> version 2:
>   - Fix bus_info not consistent between media and V4L:
>     https://www.spinics.net/lists/arm-kernel/msg717676.html
>   - Propagation of format set on video node to the sub-devices
>     chain connected on camera interface
> 
> version 1:
>   - Initial submission
> 
> Hugues Fruchet (3):
>   media: stm32-dcmi: improve sensor subdev naming
>   media: stm32-dcmi: add media controller support
>   media: stm32-dcmi: add support of several sub-devices
> 
>  drivers/media/platform/Kconfig            |   2 +-
>  drivers/media/platform/stm32/stm32-dcmi.c | 283 +++++++++++++++++++++++++-----
>  2 files changed, 236 insertions(+), 49 deletions(-)
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCHv9 1/3] arm64: dts: qcom: sdm845: Add Coresight support
From: Suzuki K Poulose @ 2019-08-07 10:12 UTC (permalink / raw)
  To: saiprakash.ranjan, mathieu.poirier, bjorn.andersson, leo.yan,
	alexander.shishkin, agross, david.brown, mark.rutland
  Cc: rnayak, marc.w.gonzalez, linux-arm-msm, linux-kernel, sibis,
	vivek.gautam, linux-arm-kernel
In-Reply-To: <b5cb08ef-ca2f-e852-f234-d0f693b58596@codeaurora.org>

Sai,

On 07/08/2019 11:08, Sai Prakash Ranjan wrote:
> Hi Suzuki,
> 
> On 7/31/2019 11:35 AM, Sai Prakash Ranjan wrote:
>> Hi Suzuki,
>>
>> On 7/31/2019 11:28 AM, Sai Prakash Ranjan wrote:
>>> Add coresight components found on Qualcomm SDM845 SoC.
>>>
>>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>>> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>>> Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> ---
>>>    arch/arm64/boot/dts/qcom/sdm845.dtsi | 451 +++++++++++++++++++++++++++
>>>    1 file changed, 451 insertions(+)
>>
>> I have tested coresight with scatter gather on SDM845 MTP and MSM8996
>> based DB820c board and posted the results in
>>
>> - https://github.com/saiprakash-ranjan/coresight-test-results
>>
>> Please let me know if you need some additional testing done.
>>
>> I could not perform coresight tests on MSM8998 MTP with latest build
>> as it was resulting in crash due to some AHB timeouts. This was not
>> due to scatter-gather and mostly likely the problem with the build.
>> Maybe we can keep msm8998-coresight on hold?
>>
>> BTW, patches are based on linux-next.
>>
> 
> Any more tests you would want me to run?

Apologies for the late response. I had seen the results and they look fine.
I was hitting some issues, which I have now root caused to firmware issues.
So we are good to go.

Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCHv9 1/3] arm64: dts: qcom: sdm845: Add Coresight support
From: Sai Prakash Ranjan @ 2019-08-07 10:08 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Bjorn Andersson, Leo Yan,
	Alexander Shishkin, Andy Gross, David Brown, Mark Rutland
  Cc: Rajendra Nayak, Marc Gonzalez, linux-arm-msm, linux-kernel,
	Sibi Sankar, Vivek Gautam, linux-arm-kernel
In-Reply-To: <b50c06d4-8298-7abe-4442-2aff336509f5@codeaurora.org>

Hi Suzuki,

On 7/31/2019 11:35 AM, Sai Prakash Ranjan wrote:
> Hi Suzuki,
> 
> On 7/31/2019 11:28 AM, Sai Prakash Ranjan wrote:
>> Add coresight components found on Qualcomm SDM845 SoC.
>>
>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>> Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>>   arch/arm64/boot/dts/qcom/sdm845.dtsi | 451 +++++++++++++++++++++++++++
>>   1 file changed, 451 insertions(+)
> 
> I have tested coresight with scatter gather on SDM845 MTP and MSM8996
> based DB820c board and posted the results in
> 
> - https://github.com/saiprakash-ranjan/coresight-test-results
> 
> Please let me know if you need some additional testing done.
> 
> I could not perform coresight tests on MSM8998 MTP with latest build
> as it was resulting in crash due to some AHB timeouts. This was not
> due to scatter-gather and mostly likely the problem with the build.
> Maybe we can keep msm8998-coresight on hold?
> 
> BTW, patches are based on linux-next.
> 

Any more tests you would want me to run?

-Sai

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH v2 4/5] firmware: arm_scmi: Add RESET protocol in SCMI v2.0
From: Peng Fan @ 2019-08-07 10:07 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel@lists.infradead.org
  Cc: aidapala@qti.qualcomm.com, Etienne Carriere, Souvik Chakravarty,
	Philipp Zabel, wesleys@xilinx.com, linux-kernel@vger.kernel.org,
	Saeed Nowshadi, Bo Zhang, Felix Burton, Jim Quinlan,
	pajay@qti.qualcomm.com, Gaku Inami, Volodymyr Babchuk
In-Reply-To: <20190806170208.6787-5-sudeep.holla@arm.com>

> Subject: [PATCH v2 4/5] firmware: arm_scmi: Add RESET protocol in SCMI
> v2.0
> 
> SCMIv2.0 adds a new Reset Management Protocol to manage various reset
> states a given device or domain can enter. Device(s) that can be collectively
> reset through a common reset signal constitute a reset domain for the
> firmware.
> 
> A reset domain can be reset autonomously or explicitly through assertion and
> de-assertion of the signal. When autonomous reset is chosen, the firmware is
> responsible for taking the necessary steps to reset the domain and to
> subsequently bring it out of reset. When explicit reset is chosen, the caller has
> to specifically assert and then de-assert the reset signal by issuing two
> separate RESET commands.
> 
> Add the basic SCMI reset infrastructure that can be used by Linux reset
> controller driver.
> 
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>  drivers/firmware/arm_scmi/Makefile |   2 +-
>  drivers/firmware/arm_scmi/reset.c  | 231
> +++++++++++++++++++++++++++++
>  include/linux/scmi_protocol.h      |  26 ++++
>  3 files changed, 258 insertions(+), 1 deletion(-)  create mode 100644
> drivers/firmware/arm_scmi/reset.c
> 
> diff --git a/drivers/firmware/arm_scmi/Makefile
> b/drivers/firmware/arm_scmi/Makefile
> index c47d28d556b6..5f298f00a82e 100644
> --- a/drivers/firmware/arm_scmi/Makefile
> +++ b/drivers/firmware/arm_scmi/Makefile
> @@ -2,5 +2,5 @@
>  obj-y	= scmi-bus.o scmi-driver.o scmi-protocols.o
>  scmi-bus-y = bus.o
>  scmi-driver-y = driver.o
> -scmi-protocols-y = base.o clock.o perf.o power.o sensors.o
> +scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
>  obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o diff
> --git a/drivers/firmware/arm_scmi/reset.c
> b/drivers/firmware/arm_scmi/reset.c
> new file mode 100644
> index 000000000000..11cb8b5ccf34
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/reset.c
> @@ -0,0 +1,231 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * System Control and Management Interface (SCMI) Reset Protocol
> + *
> + * Copyright (C) 2019 ARM Ltd.
> + */
> +
> +#include "common.h"
> +
> +enum scmi_reset_protocol_cmd {
> +	RESET_DOMAIN_ATTRIBUTES = 0x3,
> +	RESET = 0x4,
> +	RESET_NOTIFY = 0x5,
> +};
> +
> +enum scmi_reset_protocol_notify {
> +	RESET_ISSUED = 0x0,
> +};
> +
> +#define NUM_RESET_DOMAIN_MASK	0xffff
> +#define RESET_NOTIFY_ENABLE	BIT(0)
> +
> +struct scmi_msg_resp_reset_domain_attributes {
> +	__le32 attributes;
> +#define SUPPORTS_ASYNC_RESET(x)		((x) & BIT(31))
> +#define SUPPORTS_NOTIFY_RESET(x)	((x) & BIT(30))
> +	__le32 latency;
> +	    u8 name[SCMI_MAX_STR_SIZE];
> +};
> +
> +struct scmi_msg_reset_domain_reset {
> +	__le32 domain_id;
> +	__le32 flags;
> +#define AUTONOMOUS_RESET	BIT(0)
> +#define EXPLICIT_RESET_ASSERT	BIT(1)
> +#define ASYNCHRONOUS_RESET	BIT(2)
> +	__le32 reset_state;
> +#define ARCH_RESET_TYPE		BIT(31)
> +#define COLD_RESET_STATE	BIT(0)
> +#define ARCH_COLD_RESET		(ARCH_RESET_TYPE |
> COLD_RESET_STATE)
> +};
> +
> +struct reset_dom_info {
> +	bool async_reset;
> +	bool reset_notify;
> +	u32 latency_us;
> +	char name[SCMI_MAX_STR_SIZE];
> +};
> +
> +struct scmi_reset_info {
> +	int num_domains;
> +	struct reset_dom_info *dom_info;
> +};
> +
> +static int scmi_reset_attributes_get(const struct scmi_handle *handle,
> +				     struct scmi_reset_info *pi)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	u32 *attr;
> +
> +	ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
> +				 SCMI_PROTOCOL_RESET, 0, sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	attr = t->rx.buf;
> +
> +	ret = scmi_do_xfer(handle, t);
> +	if (!ret)
> +		pi->num_domains = le32_to_cpu(*attr) &
> NUM_RESET_DOMAIN_MASK;
> +
> +	scmi_xfer_put(handle, t);
> +	return ret;
> +}
> +
> +static int
> +scmi_reset_domain_attributes_get(const struct scmi_handle *handle, u32
> domain,
> +				 struct reset_dom_info *dom_info)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_resp_reset_domain_attributes *attr;
> +
> +	ret = scmi_xfer_get_init(handle, RESET_DOMAIN_ATTRIBUTES,
> +				 SCMI_PROTOCOL_RESET, sizeof(domain),
> +				 sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	*(__le32 *)t->tx.buf = cpu_to_le32(domain);
> +	attr = t->rx.buf;
> +
> +	ret = scmi_do_xfer(handle, t);
> +	if (!ret) {
> +		u32 attributes = le32_to_cpu(attr->attributes);
> +
> +		dom_info->async_reset = SUPPORTS_ASYNC_RESET(attributes);
> +		dom_info->reset_notify = SUPPORTS_NOTIFY_RESET(attributes);
> +		dom_info->latency_us = le32_to_cpu(attr->latency);
> +		if (dom_info->latency_us == U32_MAX)
> +			dom_info->latency_us = 0;
> +		strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
> +	}
> +
> +	scmi_xfer_put(handle, t);
> +	return ret;
> +}
> +
> +static int scmi_reset_num_domains_get(const struct scmi_handle *handle)
> +{
> +	struct scmi_reset_info *pi = handle->reset_priv;
> +
> +	return pi->num_domains;
> +}
> +
> +static char *scmi_reset_name_get(const struct scmi_handle *handle, u32
> +domain) {
> +	struct scmi_reset_info *pi = handle->reset_priv;
> +	struct reset_dom_info *dom = pi->dom_info + domain;
> +
> +	return dom->name;
> +}
> +
> +static int scmi_reset_latency_get(const struct scmi_handle *handle, u32
> +domain) {
> +	struct scmi_reset_info *pi = handle->reset_priv;
> +	struct reset_dom_info *dom = pi->dom_info + domain;
> +
> +	return dom->latency_us;
> +}
> +
> +static int scmi_domain_reset(const struct scmi_handle *handle, u32 domain,
> +			     u32 flags, u32 state)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_reset_domain_reset *dom;
> +	struct scmi_reset_info *pi = handle->reset_priv;
> +	struct reset_dom_info *rdom = pi->dom_info + domain;
> +
> +	if (rdom->async_reset)
> +		flags |= ASYNCHRONOUS_RESET;
> +
> +	ret = scmi_xfer_get_init(handle, RESET, SCMI_PROTOCOL_RESET,
> +				 sizeof(*dom), 0, &t);
> +	if (ret)
> +		return ret;
> +
> +	dom = t->tx.buf;
> +	dom->domain_id = cpu_to_le32(domain);
> +	dom->flags = cpu_to_le32(flags);
> +	dom->domain_id = cpu_to_le32(state);
> +
> +	if (rdom->async_reset)
> +		ret = scmi_do_xfer_with_response(handle, t);
> +	else
> +		ret = scmi_do_xfer(handle, t);
> +
> +	scmi_xfer_put(handle, t);
> +	return ret;
> +}
> +
> +static int scmi_reset_domain_reset(const struct scmi_handle *handle,
> +u32 domain) {
> +	return scmi_domain_reset(handle, domain, AUTONOMOUS_RESET,
> +				 ARCH_COLD_RESET);
> +}
> +
> +static int
> +scmi_reset_domain_assert(const struct scmi_handle *handle, u32 domain)
> +{
> +	return scmi_domain_reset(handle, domain, EXPLICIT_RESET_ASSERT,
> +				 ARCH_COLD_RESET);
> +}
> +
> +static int
> +scmi_reset_domain_deassert(const struct scmi_handle *handle, u32
> +domain) {
> +	return scmi_domain_reset(handle, domain, 0, ARCH_COLD_RESET); }
> +
> +static struct scmi_reset_ops reset_ops = {
> +	.num_domains_get = scmi_reset_num_domains_get,
> +	.name_get = scmi_reset_name_get,
> +	.latency_get = scmi_reset_latency_get,
> +	.reset = scmi_reset_domain_reset,
> +	.assert = scmi_reset_domain_assert,
> +	.deassert = scmi_reset_domain_deassert, };
> +
> +static int scmi_reset_protocol_init(struct scmi_handle *handle) {
> +	int domain;
> +	u32 version;
> +	struct scmi_reset_info *pinfo;
> +
> +	scmi_version_get(handle, SCMI_PROTOCOL_RESET, &version);
> +
> +	dev_dbg(handle->dev, "Reset Version %d.%d\n",
> +		PROTOCOL_REV_MAJOR(version),
> PROTOCOL_REV_MINOR(version));
> +
> +	pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
> +	if (!pinfo)
> +		return -ENOMEM;
> +
> +	scmi_reset_attributes_get(handle, pinfo);
> +
> +	pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
> +				       sizeof(*pinfo->dom_info), GFP_KERNEL);
> +	if (!pinfo->dom_info)
> +		return -ENOMEM;
> +
> +	for (domain = 0; domain < pinfo->num_domains; domain++) {
> +		struct reset_dom_info *dom = pinfo->dom_info + domain;
> +
> +		scmi_reset_domain_attributes_get(handle, domain, dom);
> +	}
> +
> +	handle->reset_ops = &reset_ops;
> +	handle->reset_priv = pinfo;
> +
> +	return 0;
> +}
> +
> +static int __init scmi_reset_init(void) {
> +	return scmi_protocol_register(SCMI_PROTOCOL_RESET,
> +				      &scmi_reset_protocol_init);
> +}
> +subsys_initcall(scmi_reset_init);
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index f0f2b53a1dac..881fea47c83d 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -187,6 +187,26 @@ struct scmi_sensor_ops {
>  			   u64 *value);
>  };
> 
> +/**
> + * struct scmi_reset_ops - represents the various operations provided
> + *	by SCMI Reset Protocol
> + *
> + * @num_domains_get: get the count of reset domains provided by SCMI
> + * @name_get: gets the name of a reset domain
> + * @latency_get: gets the reset latency for the specified reset domain
> + * @reset: resets the specified reset domain
> + * @assert: explicitly assert reset signal of the specified reset
> +domain
> + * @deassert: explicitly deassert reset signal of the specified reset
> +domain  */ struct scmi_reset_ops {
> +	int (*num_domains_get)(const struct scmi_handle *handle);
> +	char *(*name_get)(const struct scmi_handle *handle, u32 domain);
> +	int (*latency_get)(const struct scmi_handle *handle, u32 domain);
> +	int (*reset)(const struct scmi_handle *handle, u32 domain);
> +	int (*assert)(const struct scmi_handle *handle, u32 domain);
> +	int (*deassert)(const struct scmi_handle *handle, u32 domain); };
> +
>  /**
>   * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
>   *
> @@ -196,6 +216,7 @@ struct scmi_sensor_ops {
>   * @perf_ops: pointer to set of performance protocol operations
>   * @clk_ops: pointer to set of clock protocol operations
>   * @sensor_ops: pointer to set of sensor protocol operations
> + * @reset_ops: pointer to set of reset protocol operations
>   * @perf_priv: pointer to private data structure specific to performance
>   *	protocol(for internal use only)
>   * @clk_priv: pointer to private data structure specific to clock @@ -204,6
> +225,8 @@ struct scmi_sensor_ops {
>   *	protocol(for internal use only)
>   * @sensor_priv: pointer to private data structure specific to sensors
>   *	protocol(for internal use only)
> + * @reset_priv: pointer to private data structure specific to reset
> + *	protocol(for internal use only)
>   */
>  struct scmi_handle {
>  	struct device *dev;
> @@ -212,11 +235,13 @@ struct scmi_handle {
>  	struct scmi_clk_ops *clk_ops;
>  	struct scmi_power_ops *power_ops;
>  	struct scmi_sensor_ops *sensor_ops;
> +	struct scmi_reset_ops *reset_ops;
>  	/* for protocol internal use */
>  	void *perf_priv;
>  	void *clk_priv;
>  	void *power_priv;
>  	void *sensor_priv;
> +	void *reset_priv;
>  };
> 
>  enum scmi_std_protocol {
> @@ -226,6 +251,7 @@ enum scmi_std_protocol {
>  	SCMI_PROTOCOL_PERF = 0x13,
>  	SCMI_PROTOCOL_CLOCK = 0x14,
>  	SCMI_PROTOCOL_SENSOR = 0x15,
> +	SCMI_PROTOCOL_RESET = 0x16,
>  };

Reviewed-by: Peng Fan <peng.fan@nxp.com>

> 
>  struct scmi_device {
> --
> 2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH v2 2/5] firmware: arm_scmi: Make use SCMI v2.0 fastchannel for performance protocol
From: Peng Fan @ 2019-08-07 10:01 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel@lists.infradead.org
  Cc: aidapala@qti.qualcomm.com, Etienne Carriere, Souvik Chakravarty,
	wesleys@xilinx.com, Ionela Voinescu, linux-kernel@vger.kernel.org,
	Saeed Nowshadi, Quentin Perret, Bo Zhang, Felix Burton,
	Jim Quinlan, Chris Redpath, pajay@qti.qualcomm.com, Gaku Inami,
	Volodymyr Babchuk, dl-linux-imx
In-Reply-To: <20190806170208.6787-3-sudeep.holla@arm.com>

> Subject: [PATCH v2 2/5] firmware: arm_scmi: Make use SCMI v2.0
> fastchannel for performance protocol
> 
> SCMI v2.0 adds support for "FastChannel" which do not use a message
> header as they are specialized for a single message.
> 
> Only PERFORMANCE_LIMITS_{SET,GET} and
> PERFORMANCE_LEVEL_{SET,GET} commands are supported over
> fastchannels. As they are optional, they need to be discovered by
> PERFORMANCE_DESCRIBE_FASTCHANNEL command.
> Further {LIMIT,LEVEL}_SET commands can have optional doorbell support.
> 
> Add support for making use of these fastchannels.
> 
> Cc: Ionela Voinescu <Ionela.Voinescu@arm.com>
> Cc: Chris Redpath <Chris.Redpath@arm.com>
> Cc: Quentin Perret <Quentin.Perret@arm.com>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>  drivers/firmware/arm_scmi/perf.c | 104
> +++++++++++++++++++++++++++++--
>  1 file changed, 100 insertions(+), 4 deletions(-)
> 
> v1->v2:
> 	- Changed the macro SCMI_PERF_FC_RING_DB to use do {} while(0)
> 
> diff --git a/drivers/firmware/arm_scmi/perf.c
> b/drivers/firmware/arm_scmi/perf.c
> index 6cce3e82e81e..fb7f6cab2c11 100644
> --- a/drivers/firmware/arm_scmi/perf.c
> +++ b/drivers/firmware/arm_scmi/perf.c
> @@ -8,6 +8,7 @@
>  #include <linux/bits.h>
>  #include <linux/of.h>
>  #include <linux/io.h>
> +#include <linux/io-64-nonatomic-hi-lo.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_opp.h>
>  #include <linux/sort.h>
> @@ -293,7 +294,42 @@ scmi_perf_describe_levels_get(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> -static int scmi_perf_limits_set(const struct scmi_handle *handle, u32
> domain,
> +#define SCMI_PERF_FC_RING_DB(doorbell, w)		\
> +do {							\
> +	u##w val = 0;					\
> +	struct scmi_fc_db_info *db = doorbell;		\
> +							\
> +	if (db->mask)					\
> +		val = ioread##w(db->addr) & db->mask;	\
> +	iowrite##w((u##w)db->set | val, db->addr);	\
> +} while(0)
> +
> +static void scmi_perf_fc_ring_db(struct scmi_fc_db_info *db) {
> +	if (!db || !db->addr)
> +		return;
> +
> +	if (db->width == 1)
> +		SCMI_PERF_FC_RING_DB(db, 8);
> +	else if (db->width == 2)
> +		SCMI_PERF_FC_RING_DB(db, 16);
> +	else if (db->width == 4)
> +		SCMI_PERF_FC_RING_DB(db, 32);
> +	else /* db->width == 8 */
> +#ifdef CONFIG_64BIT
> +		SCMI_PERF_FC_RING_DB(db, 64);
> +#else
> +	{
> +		u64 val = 0;
> +
> +		if (db->mask)
> +			val = ioread64_hi_lo(db->addr) & db->mask;
> +		iowrite64_hi_lo(db->set, db->addr);
> +	}
> +#endif
> +}
> +
> +static int scmi_perf_mb_limits_set(const struct scmi_handle *handle,
> +u32 domain,
>  				   u32 max_perf, u32 min_perf)
>  {
>  	int ret;
> @@ -316,7 +352,23 @@ static int scmi_perf_limits_set(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> -static int scmi_perf_limits_get(const struct scmi_handle *handle, u32
> domain,
> +static int scmi_perf_limits_set(const struct scmi_handle *handle, u32
> domain,
> +				u32 max_perf, u32 min_perf)
> +{
> +	struct scmi_perf_info *pi = handle->perf_priv;
> +	struct perf_dom_info *dom = pi->dom_info + domain;
> +
> +	if (dom->fc_info && dom->fc_info->limit_set_addr) {
> +		iowrite32(max_perf, dom->fc_info->limit_set_addr);
> +		iowrite32(min_perf, dom->fc_info->limit_set_addr + 4);
> +		scmi_perf_fc_ring_db(dom->fc_info->limit_set_db);
> +		return 0;
> +	}
> +
> +	return scmi_perf_mb_limits_set(handle, domain, max_perf, min_perf); }
> +
> +static int scmi_perf_mb_limits_get(const struct scmi_handle *handle,
> +u32 domain,
>  				   u32 *max_perf, u32 *min_perf)
>  {
>  	int ret;
> @@ -342,7 +394,22 @@ static int scmi_perf_limits_get(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> -static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
> +static int scmi_perf_limits_get(const struct scmi_handle *handle, u32
> domain,
> +				u32 *max_perf, u32 *min_perf)
> +{
> +	struct scmi_perf_info *pi = handle->perf_priv;
> +	struct perf_dom_info *dom = pi->dom_info + domain;
> +
> +	if (dom->fc_info && dom->fc_info->limit_get_addr) {
> +		*max_perf = ioread32(dom->fc_info->limit_get_addr);
> +		*min_perf = ioread32(dom->fc_info->limit_get_addr + 4);
> +		return 0;
> +	}
> +
> +	return scmi_perf_mb_limits_get(handle, domain, max_perf, min_perf); }
> +
> +static int scmi_perf_mb_level_set(const struct scmi_handle *handle, u32
> +domain,
>  				  u32 level, bool poll)
>  {
>  	int ret;
> @@ -365,7 +432,22 @@ static int scmi_perf_level_set(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> -static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
> +static int scmi_perf_level_set(const struct scmi_handle *handle, u32
> domain,
> +			       u32 level, bool poll)
> +{
> +	struct scmi_perf_info *pi = handle->perf_priv;
> +	struct perf_dom_info *dom = pi->dom_info + domain;
> +
> +	if (dom->fc_info && dom->fc_info->level_set_addr) {
> +		iowrite32(level, dom->fc_info->level_set_addr);
> +		scmi_perf_fc_ring_db(dom->fc_info->level_set_db);
> +		return 0;
> +	}
> +
> +	return scmi_perf_mb_level_set(handle, domain, level, poll); }
> +
> +static int scmi_perf_mb_level_get(const struct scmi_handle *handle, u32
> +domain,
>  				  u32 *level, bool poll)
>  {
>  	int ret;
> @@ -387,6 +469,20 @@ static int scmi_perf_level_get(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> +static int scmi_perf_level_get(const struct scmi_handle *handle, u32
> domain,
> +			       u32 *level, bool poll)
> +{
> +	struct scmi_perf_info *pi = handle->perf_priv;
> +	struct perf_dom_info *dom = pi->dom_info + domain;
> +
> +	if (dom->fc_info && dom->fc_info->level_get_addr) {
> +		*level = ioread32(dom->fc_info->level_get_addr);
> +		return 0;
> +	}
> +
> +	return scmi_perf_mb_level_get(handle, domain, level, poll); }
> +
>  static bool scmi_perf_fc_size_is_valid(u32 msg, u32 size)  {
>  	if ((msg == PERF_LEVEL_GET || msg == PERF_LEVEL_SET) && size == 4)

Reviewed-by: Peng Fan <peng.fan@nxp.com>

> --
> 2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] KVM: arm/arm64: vgic: Reevaluate level sensitive interrupts on enable
From: Alexandru Elisei @ 2019-08-07  9:53 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm
  Cc: maz, andre.przywara, christoffer.dall, eric.auger

A HW mapped level sensitive interrupt asserted by a device will not be put
into the ap_list if it is disabled at the VGIC level. When it is enabled
again, it will be inserted into the ap_list and written to a list register
on guest entry regardless of the state of the device.

We could argue that this can also happen on real hardware, when the command
to enable the interrupt reached the GIC before the device had the chance to
de-assert the interrupt signal; however, we emulate the distributor and
redistributors in software and we can do better than that.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 3ba7278fb533..44efc2ff863f 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -113,6 +113,22 @@ void vgic_mmio_write_senable(struct kvm_vcpu *vcpu,
 		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
 
 		raw_spin_lock_irqsave(&irq->irq_lock, flags);
+		if (vgic_irq_is_mapped_level(irq)) {
+			bool was_high = irq->line_level;
+
+			/*
+			 * We need to update the state of the interrupt because
+			 * the guest might have changed the state of the device
+			 * while the interrupt was disabled at the VGIC level.
+			 */
+			irq->line_level = vgic_get_phys_line_level(irq);
+			/*
+			 * Deactivate the physical interrupt so the GIC will let
+			 * us know when it is asserted again.
+			 */
+			if (!irq->active && was_high && !irq->line_level)
+				vgic_irq_set_phys_active(irq, false);
+		}
 		irq->enabled = true;
 		vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
 
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 3/3] ARM: OMAP2+: omap-iommu.c conversion to ti-sysc
From: Tero Kristo @ 2019-08-07  9:44 UTC (permalink / raw)
  To: linux-omap, tony; +Cc: linux-arm-kernel
In-Reply-To: <1565171081-7899-1-git-send-email-t-kristo@ti.com>

Convert omap2 iommu platform code to use ti-sysc instead of legacy
omap-device / hwmod interfaces.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap-iommu.c | 99 ++++++++++++++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 8f6b6b8..f8cbf6b 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -16,19 +16,27 @@
 
 #include <linux/platform_device.h>
 #include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/list.h>
 
-#include "omap_hwmod.h"
-#include "omap_device.h"
 #include "clockdomain.h"
 #include "powerdomain.h"
 
+struct pwrdm_link {
+	struct device *dev;
+	struct powerdomain *pwrdm;
+	struct list_head node;
+};
+
+static DEFINE_SPINLOCK(iommu_lock);
+static struct clockdomain *emu_clkdm;
+static atomic_t emu_count;
+
 static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
 					     bool enable)
 {
-	static struct clockdomain *emu_clkdm;
-	static DEFINE_SPINLOCK(emu_lock);
-	static atomic_t count;
 	struct device_node *np = pdev->dev.of_node;
+	unsigned long flags;
 
 	if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
 		return;
@@ -39,34 +47,87 @@ static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
 			return;
 	}
 
-	spin_lock(&emu_lock);
+	spin_lock_irqsave(&iommu_lock, flags);
 
-	if (enable && (atomic_inc_return(&count) == 1))
+	if (enable && (atomic_inc_return(&emu_count) == 1))
 		clkdm_deny_idle(emu_clkdm);
-	else if (!enable && (atomic_dec_return(&count) == 0))
+	else if (!enable && (atomic_dec_return(&emu_count) == 0))
 		clkdm_allow_idle(emu_clkdm);
 
-	spin_unlock(&emu_lock);
+	spin_unlock_irqrestore(&iommu_lock, flags);
+}
+
+static struct powerdomain *_get_pwrdm(struct device *dev)
+{
+	struct clk *clk;
+	struct clk_hw_omap *hwclk;
+	struct clockdomain *clkdm;
+	struct powerdomain *pwrdm = NULL;
+	struct pwrdm_link *entry;
+	unsigned long flags;
+	static LIST_HEAD(cache);
+
+	spin_lock_irqsave(&iommu_lock, flags);
+
+	list_for_each_entry(entry, &cache, node) {
+		if (entry->dev == dev) {
+			pwrdm = entry->pwrdm;
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&iommu_lock, flags);
+
+	if (pwrdm)
+		return pwrdm;
+
+	clk = of_clk_get(dev->of_node->parent, 0);
+	if (!clk) {
+		dev_err(dev, "no fck found\n");
+		return NULL;
+	}
+
+	hwclk = to_clk_hw_omap(__clk_get_hw(clk));
+	clk_put(clk);
+	if (!hwclk || !hwclk->clkdm_name) {
+		dev_err(dev, "no hwclk data\n");
+		return NULL;
+	}
+
+	clkdm = clkdm_lookup(hwclk->clkdm_name);
+	if (!clkdm) {
+		dev_err(dev, "clkdm not found: %s\n", hwclk->clkdm_name);
+		return NULL;
+	}
+
+	pwrdm = clkdm_get_pwrdm(clkdm);
+	if (!pwrdm) {
+		dev_err(dev, "pwrdm not found: %s\n", clkdm->name);
+		return NULL;
+	}
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (entry) {
+		entry->dev = dev;
+		entry->pwrdm = pwrdm;
+		spin_lock_irqsave(&iommu_lock, flags);
+		list_add(&entry->node, &cache);
+		spin_unlock_irqrestore(&iommu_lock, flags);
+	}
+
+	return pwrdm;
 }
 
 int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
 				    u8 *pwrst)
 {
 	struct powerdomain *pwrdm;
-	struct omap_device *od;
 	u8 next_pwrst;
 	int ret = 0;
 
-	od = to_omap_device(pdev);
-	if (!od)
-		return -ENODEV;
-
-	if (od->hwmods_cnt != 1)
-		return -EINVAL;
-
-	pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
+	pwrdm = _get_pwrdm(&pdev->dev);
 	if (!pwrdm)
-		return -EINVAL;
+		return -ENODEV;
 
 	if (request) {
 		*pwrst = pwrdm_read_next_pwrst(pwrdm);
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 2/3] ARM: OMAP2+: Add workaround for DRA7 DSP MStandby errata i879
From: Tero Kristo @ 2019-08-07  9:44 UTC (permalink / raw)
  To: linux-omap, tony; +Cc: linux-arm-kernel
In-Reply-To: <1565171081-7899-1-git-send-email-t-kristo@ti.com>

From: Suman Anna <s-anna@ti.com>

Errata Title:
i879: DSP MStandby requires CD_EMU in SW_WKUP

Description:
The DSP requires the internal emulation clock to be actively toggling
in order to successfully enter a low power mode via execution of the
IDLE instruction and PRCM MStandby/Idle handshake. This assumes that
other prerequisites and software sequence are followed.

Workaround:
The emulation clock to the DSP is free-running anytime CCS is connected
via JTAG debugger to the DSP subsystem or when the CD_EMU clock domain
is set in SW_WKUP mode. The CD_EMU domain can be set in SW_WKUP mode
via the CM_EMU_CLKSTCTRL [1:0]CLKTRCTRL field.

Implementation:
This patch implements this workaround by denying the HW_AUTO mode
for the EMU clockdomain during the power-up of any DSP processor
and re-enabling the HW_AUTO mode during the shutdown of the last
DSP processor (actually done during the enabling and disabling of
the respective DSP MDMA MMUs). Reference counting has to be used to
manage the independent sequencing between the multiple DSP processors.

This switching is done at runtime rather than a static clockdomain
flags value to meet the target power domain state for the EMU power
domain during suspend.

Note that the DSP MStandby behavior is not consistent across all
boards prior to this fix. Please see commit 45f871eec6c0 ("ARM:
OMAP2+: Extend DRA7 IPU1 MMU pdata quirks to DSP MDMA MMUs") for
details.

Signed-off-by: Suman Anna <s-anna@ti.com>
---
 arch/arm/mach-omap2/omap-iommu.c | 43 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 1392a5b..8f6b6b8 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -19,14 +19,43 @@
 
 #include "omap_hwmod.h"
 #include "omap_device.h"
+#include "clockdomain.h"
 #include "powerdomain.h"
 
+static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
+					     bool enable)
+{
+	static struct clockdomain *emu_clkdm;
+	static DEFINE_SPINLOCK(emu_lock);
+	static atomic_t count;
+	struct device_node *np = pdev->dev.of_node;
+
+	if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
+		return;
+
+	if (!emu_clkdm) {
+		emu_clkdm = clkdm_lookup("emu_clkdm");
+		if (WARN_ON_ONCE(!emu_clkdm))
+			return;
+	}
+
+	spin_lock(&emu_lock);
+
+	if (enable && (atomic_inc_return(&count) == 1))
+		clkdm_deny_idle(emu_clkdm);
+	else if (!enable && (atomic_dec_return(&count) == 0))
+		clkdm_allow_idle(emu_clkdm);
+
+	spin_unlock(&emu_lock);
+}
+
 int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
 				    u8 *pwrst)
 {
 	struct powerdomain *pwrdm;
 	struct omap_device *od;
 	u8 next_pwrst;
+	int ret = 0;
 
 	od = to_omap_device(pdev);
 	if (!od)
@@ -39,13 +68,21 @@ int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
 	if (!pwrdm)
 		return -EINVAL;
 
-	if (request)
+	if (request) {
 		*pwrst = pwrdm_read_next_pwrst(pwrdm);
+		omap_iommu_dra7_emu_swsup_config(pdev, true);
+	}
 
 	if (*pwrst > PWRDM_POWER_RET)
-		return 0;
+		goto out;
 
 	next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
 
-	return pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+	ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+
+out:
+	if (!request)
+		omap_iommu_dra7_emu_swsup_config(pdev, false);
+
+	return ret;
 }
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 1/3] ARM: OMAP4+: remove pdata quirks for omap4+ iommus
From: Tero Kristo @ 2019-08-07  9:44 UTC (permalink / raw)
  To: linux-omap, tony; +Cc: linux-arm-kernel
In-Reply-To: <1565171081-7899-1-git-send-email-t-kristo@ti.com>

IOMMU driver will be using ti-sysc bus driver for power management control
going forward, and the pdata quirks are not needed for anything anymore.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pdata-quirks.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 6c6f8fc..58fb0de 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -419,14 +419,6 @@ static void __init omap3_pandora_legacy_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
-#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-static struct iommu_platform_data omap4_iommu_pdata = {
-	.reset_name = "mmu_cache",
-	.assert_reset = omap_device_assert_hardreset,
-	.deassert_reset = omap_device_deassert_hardreset,
-};
-#endif
-
 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 static struct wkup_m3_platform_data wkup_m3_data = {
 	.reset_name = "wkup_m3",
@@ -642,10 +634,6 @@ static void __init omap3_mcbsp_init(void) {}
 		       &wkup_m3_data),
 #endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-	OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
-		       &omap4_iommu_pdata),
-	OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
-		       &omap4_iommu_pdata),
 	OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000,
 		       "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]),
 	OF_DEV_AUXDATA("ti,omap4-smartreflex-core", 0x4a0dd000,
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 0/3] ARM: OMAP2+: pdata quirk fixes for OMAP IOMMUs
From: Tero Kristo @ 2019-08-07  9:44 UTC (permalink / raw)
  To: linux-omap, tony; +Cc: linux-arm-kernel

Hi,

A few quick fixes for OMAP IOMMU pdata quirks. These basically apply
one errata for remoteprocs, and also convert the support of iommus
to ti-sysc from hwmod for omap4+ devices.

-Tero

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] arm64: mm: add missing PTE_SPECIAL in pte_mkdevmap on arm64
From: Catalin Marinas @ 2019-08-07  9:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: Mark Rutland, Jia He, Anshuman Khandual, Christoffer Dall,
	linux-kernel, Jun Yao, James Morse, Punit Agrawal, Qian Cai,
	Thomas Gleixner, Robin Murphy, Alex Van Brunt, linux-arm-kernel
In-Reply-To: <20190807090929.zsiupxyqop75uzkn@willie-the-truck>

On Wed, Aug 07, 2019 at 10:09:29AM +0100, Will Deacon wrote:
> On Wed, Aug 07, 2019 at 12:58:51PM +0800, Jia He wrote:
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 5fdcfe237338..e09760ece844 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -209,7 +209,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
> >  
> >  static inline pte_t pte_mkdevmap(pte_t pte)
> >  {
> > -	return set_pte_bit(pte, __pgprot(PTE_DEVMAP));
> > +	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
> >  }
> >  
> >  static inline void set_pte(pte_t *ptep, pte_t pte)
> > @@ -396,7 +396,10 @@ static inline int pmd_protnone(pmd_t pmd)
> >  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> >  #define pmd_devmap(pmd)		pte_devmap(pmd_pte(pmd))
> >  #endif
> > -#define pmd_mkdevmap(pmd)	pte_pmd(pte_mkdevmap(pmd_pte(pmd)))
> > +static inline pmd_t pmd_mkdevmap(pmd_t pmd)
> > +{
> > +	return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
> > +}
> >  
> >  #define __pmd_to_phys(pmd)	__pte_to_phys(pmd_pte(pmd))
> >  #define __phys_to_pmd_val(phys)	__phys_to_pte_val(phys)
> 
> Acked-by: Will Deacon <will@kernel.org>
> 
> I think Catalin can take this as a fix, although the commit message should
> probably be trimmed down a bit to remove the two call traces etc.

I'll queue this for -rc4 and sort out the commit message. Thanks.

-- 
Catalin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH v2 1/5] firmware: arm_scmi: Add discovery of SCMI v2.0 performance fastchannels
From: Peng Fan @ 2019-08-07  9:23 UTC (permalink / raw)
  To: Sudeep Holla, linux-arm-kernel@lists.infradead.org
  Cc: aidapala@qti.qualcomm.com, Etienne Carriere, Souvik Chakravarty,
	wesleys@xilinx.com, Ionela Voinescu, linux-kernel@vger.kernel.org,
	Saeed Nowshadi, Quentin Perret, Bo Zhang, Felix Burton,
	Jim Quinlan, Chris Redpath, pajay@qti.qualcomm.com, Gaku Inami,
	Volodymyr Babchuk
In-Reply-To: <20190806170208.6787-2-sudeep.holla@arm.com>

> Subject: [PATCH v2 1/5] firmware: arm_scmi: Add discovery of SCMI v2.0
> performance fastchannels
> 
> SCMI v2.0 adds support for "FastChannel", a lightweight unidirectional
> channel that is dedicated to a single SCMI message type for controlling a
> specific platform resource. They do not use a message header as they are
> specialized for a single message.
> 
> Only PERFORMANCE_LIMITS_{SET,GET} and
> PERFORMANCE_LEVEL_{SET,GET} commands are supported over
> fastchannels. As they are optional, they need to be discovered by
> PERFORMANCE_DESCRIBE_FASTCHANNEL command.
> Further {LIMIT,LEVEL}_SET commands can have optional doorbell support.
> 
> Add support for discovery of these fastchannels.
> 
> Cc: Ionela Voinescu <Ionela.Voinescu@arm.com>
> Cc: Chris Redpath <Chris.Redpath@arm.com>
> Cc: Quentin Perret <Quentin.Perret@arm.com>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>  drivers/firmware/arm_scmi/perf.c | 153
> ++++++++++++++++++++++++++++++-
>  1 file changed, 149 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/perf.c
> b/drivers/firmware/arm_scmi/perf.c
> index 3c8ae7cc35de..6cce3e82e81e 100644
> --- a/drivers/firmware/arm_scmi/perf.c
> +++ b/drivers/firmware/arm_scmi/perf.c
> @@ -5,7 +5,9 @@
>   * Copyright (C) 2018 ARM Ltd.
>   */
> 
> +#include <linux/bits.h>
>  #include <linux/of.h>
> +#include <linux/io.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_opp.h>
>  #include <linux/sort.h>
> @@ -21,6 +23,7 @@ enum scmi_performance_protocol_cmd {
>  	PERF_LEVEL_GET = 0x8,
>  	PERF_NOTIFY_LIMITS = 0x9,
>  	PERF_NOTIFY_LEVEL = 0xa,
> +	PERF_DESCRIBE_FASTCHANNEL = 0xb,
>  };
> 
>  struct scmi_opp {
> @@ -44,6 +47,7 @@ struct scmi_msg_resp_perf_domain_attributes {
>  #define SUPPORTS_SET_PERF_LVL(x)	((x) & BIT(30))
>  #define SUPPORTS_PERF_LIMIT_NOTIFY(x)	((x) & BIT(29))
>  #define SUPPORTS_PERF_LEVEL_NOTIFY(x)	((x) & BIT(28))
> +#define SUPPORTS_PERF_FASTCHANNELS(x)	((x) & BIT(27))
>  	__le32 rate_limit_us;
>  	__le32 sustained_freq_khz;
>  	__le32 sustained_perf_level;
> @@ -87,17 +91,56 @@ struct scmi_msg_resp_perf_describe_levels {
>  	} opp[0];
>  };
> 
> +struct scmi_perf_get_fc_info {
> +	__le32 domain;
> +	__le32 message_id;
> +};
> +
> +struct scmi_msg_resp_perf_desc_fc {
> +	__le32 attr;
> +#define SUPPORTS_DOORBELL(x)		((x) & BIT(0))
> +#define DOORBELL_REG_WIDTH(x)		FIELD_GET(GENMASK(2, 1), (x))
> +	__le32 rate_limit;
> +	__le32 chan_addr_low;
> +	__le32 chan_addr_high;
> +	__le32 chan_size;
> +	__le32 db_addr_low;
> +	__le32 db_addr_high;
> +	__le32 db_set_lmask;
> +	__le32 db_set_hmask;
> +	__le32 db_preserve_lmask;
> +	__le32 db_preserve_hmask;
> +};
> +
> +struct scmi_fc_db_info {
> +	int width;
> +	u64 set;
> +	u64 mask;
> +	void __iomem *addr;
> +};
> +
> +struct scmi_fc_info {
> +	void __iomem *level_set_addr;
> +	void __iomem *limit_set_addr;
> +	void __iomem *level_get_addr;
> +	void __iomem *limit_get_addr;
> +	struct scmi_fc_db_info *level_set_db;
> +	struct scmi_fc_db_info *limit_set_db;
> +};
> +
>  struct perf_dom_info {
>  	bool set_limits;
>  	bool set_perf;
>  	bool perf_limit_notify;
>  	bool perf_level_notify;
> +	bool perf_fastchannels;
>  	u32 opp_count;
>  	u32 sustained_freq_khz;
>  	u32 sustained_perf_level;
>  	u32 mult_factor;
>  	char name[SCMI_MAX_STR_SIZE];
>  	struct scmi_opp opp[MAX_OPPS];
> +	struct scmi_fc_info *fc_info;
>  };
> 
>  struct scmi_perf_info {
> @@ -162,6 +205,7 @@ scmi_perf_domain_attributes_get(const struct
> scmi_handle *handle, u32 domain,
>  		dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags);
>  		dom_info->perf_limit_notify =
> SUPPORTS_PERF_LIMIT_NOTIFY(flags);
>  		dom_info->perf_level_notify =
> SUPPORTS_PERF_LEVEL_NOTIFY(flags);
> +		dom_info->perf_fastchannels =
> SUPPORTS_PERF_FASTCHANNELS(flags);
>  		dom_info->sustained_freq_khz =
>  					le32_to_cpu(attr->sustained_freq_khz);
>  		dom_info->sustained_perf_level =
> @@ -250,7 +294,7 @@ scmi_perf_describe_levels_get(const struct
> scmi_handle *handle, u32 domain,  }
> 
>  static int scmi_perf_limits_set(const struct scmi_handle *handle, u32
> domain,
> -				u32 max_perf, u32 min_perf)
> +				   u32 max_perf, u32 min_perf)
>  {
>  	int ret;
>  	struct scmi_xfer *t;
> @@ -273,7 +317,7 @@ static int scmi_perf_limits_set(const struct
> scmi_handle *handle, u32 domain,  }
> 
>  static int scmi_perf_limits_get(const struct scmi_handle *handle, u32
> domain,
> -				u32 *max_perf, u32 *min_perf)
> +				   u32 *max_perf, u32 *min_perf)
>  {
>  	int ret;
>  	struct scmi_xfer *t;
> @@ -299,7 +343,7 @@ static int scmi_perf_limits_get(const struct
> scmi_handle *handle, u32 domain,  }
> 
>  static int scmi_perf_level_set(const struct scmi_handle *handle, u32
> domain,
> -			       u32 level, bool poll)
> +				  u32 level, bool poll)
>  {
>  	int ret;
>  	struct scmi_xfer *t;
> @@ -322,7 +366,7 @@ static int scmi_perf_level_set(const struct
> scmi_handle *handle, u32 domain,  }
> 
>  static int scmi_perf_level_get(const struct scmi_handle *handle, u32
> domain,
> -			       u32 *level, bool poll)
> +				  u32 *level, bool poll)
>  {
>  	int ret;
>  	struct scmi_xfer *t;
> @@ -343,6 +387,104 @@ static int scmi_perf_level_get(const struct
> scmi_handle *handle, u32 domain,
>  	return ret;
>  }
> 
> +static bool scmi_perf_fc_size_is_valid(u32 msg, u32 size) {
> +	if ((msg == PERF_LEVEL_GET || msg == PERF_LEVEL_SET) && size == 4)
> +		return true;
> +	if ((msg == PERF_LIMITS_GET || msg == PERF_LIMITS_SET) && size == 8)
> +		return true;
> +	return false;
> +}
> +
> +static void
> +scmi_perf_domain_desc_fc(const struct scmi_handle *handle, u32 domain,
> +			 u32 message_id, void __iomem **p_addr,
> +			 struct scmi_fc_db_info **p_db)
> +{
> +	int ret;
> +	u32 flags;
> +	u64 phys_addr;
> +	u8 size;
> +	void __iomem *addr;
> +	struct scmi_xfer *t;
> +	struct scmi_fc_db_info *db;
> +	struct scmi_perf_get_fc_info *info;
> +	struct scmi_msg_resp_perf_desc_fc *resp;
> +
> +	if (!p_addr)
> +		return;
> +
> +	ret = scmi_xfer_get_init(handle, PERF_DESCRIBE_FASTCHANNEL,
> +				 SCMI_PROTOCOL_PERF,
> +				 sizeof(*info), sizeof(*resp), &t);
> +	if (ret)
> +		return;
> +
> +	info = t->tx.buf;
> +	info->domain = cpu_to_le32(domain);
> +	info->message_id = cpu_to_le32(message_id);
> +
> +	ret = scmi_do_xfer(handle, t);
> +	if (ret)
> +		goto err_xfer;
> +
> +	resp = t->rx.buf;
> +	flags = le32_to_cpu(resp->attr);
> +	size = le32_to_cpu(resp->chan_size);
> +	if (!scmi_perf_fc_size_is_valid(message_id, size))
> +		goto err_xfer;
> +
> +	phys_addr = le32_to_cpu(resp->chan_addr_low);
> +	phys_addr |= (u64)le32_to_cpu(resp->chan_addr_high) << 32;
> +	addr = devm_ioremap(handle->dev, phys_addr, size);
> +	if (!addr)
> +		goto err_xfer;
> +	*p_addr = addr;
> +
> +	if (p_db && SUPPORTS_DOORBELL(flags)) {
> +		db = devm_kzalloc(handle->dev, sizeof(*db), GFP_KERNEL);
> +		if (!db)
> +			goto err_xfer;
> +
> +		size = 1 << DOORBELL_REG_WIDTH(flags);
> +		phys_addr = le32_to_cpu(resp->db_addr_low);
> +		phys_addr |= (u64)le32_to_cpu(resp->db_addr_high) << 32;
> +		addr = devm_ioremap(handle->dev, phys_addr, size);
> +		if (!addr)
> +			goto err_xfer;
> +
> +		db->addr = addr;
> +		db->width = size;
> +		db->set = le32_to_cpu(resp->db_set_lmask);
> +		db->set |= (u64)le32_to_cpu(resp->db_set_hmask) << 32;
> +		db->mask = le32_to_cpu(resp->db_preserve_lmask);
> +		db->mask |= (u64)le32_to_cpu(resp->db_preserve_hmask) << 32;
> +		*p_db = db;
> +	}
> +err_xfer:
> +	scmi_xfer_put(handle, t);
> +}
> +
> +static void scmi_perf_domain_init_fc(const struct scmi_handle *handle,
> +				     u32 domain, struct scmi_fc_info **p_fc) {
> +	struct scmi_fc_info *fc;
> +
> +	fc = devm_kzalloc(handle->dev, sizeof(*fc), GFP_KERNEL);
> +	if (!fc)
> +		return;
> +
> +	scmi_perf_domain_desc_fc(handle, domain, PERF_LEVEL_SET,
> +				 &fc->level_set_addr, &fc->level_set_db);
> +	scmi_perf_domain_desc_fc(handle, domain, PERF_LEVEL_GET,
> +				 &fc->level_get_addr, NULL);
> +	scmi_perf_domain_desc_fc(handle, domain, PERF_LIMITS_SET,
> +				 &fc->limit_set_addr, &fc->limit_set_db);
> +	scmi_perf_domain_desc_fc(handle, domain, PERF_LIMITS_GET,
> +				 &fc->limit_get_addr, NULL);
> +	*p_fc = fc;
> +}
> +
>  /* Device specific ops */
>  static int scmi_dev_domain_id(struct device *dev)  { @@ -494,6 +636,9
> @@ static int scmi_perf_protocol_init(struct scmi_handle *handle)
> 
>  		scmi_perf_domain_attributes_get(handle, domain, dom);
>  		scmi_perf_describe_levels_get(handle, domain, dom);
> +
> +		if (dom->perf_fastchannels)
> +			scmi_perf_domain_init_fc(handle, domain, &dom->fc_info);
>  	}
> 
>  	handle->perf_ops = &perf_ops;

Reviewed-by: Peng Fan <peng.fan@nxp.com>

> --
> 2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] arm64: mm: add missing PTE_SPECIAL in pte_mkdevmap on arm64
From: Will Deacon @ 2019-08-07  9:09 UTC (permalink / raw)
  To: Jia He
  Cc: Mark Rutland, Anshuman Khandual, Catalin Marinas,
	Christoffer Dall, linux-kernel, Jun Yao, Qian Cai, Punit Agrawal,
	James Morse, Thomas Gleixner, Robin Murphy, Alex Van Brunt,
	linux-arm-kernel
In-Reply-To: <20190807045851.10772-1-justin.he@arm.com>

On Wed, Aug 07, 2019 at 12:58:51PM +0800, Jia He wrote:
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 5fdcfe237338..e09760ece844 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -209,7 +209,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
>  
>  static inline pte_t pte_mkdevmap(pte_t pte)
>  {
> -	return set_pte_bit(pte, __pgprot(PTE_DEVMAP));
> +	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
>  }
>  
>  static inline void set_pte(pte_t *ptep, pte_t pte)
> @@ -396,7 +396,10 @@ static inline int pmd_protnone(pmd_t pmd)
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define pmd_devmap(pmd)		pte_devmap(pmd_pte(pmd))
>  #endif
> -#define pmd_mkdevmap(pmd)	pte_pmd(pte_mkdevmap(pmd_pte(pmd)))
> +static inline pmd_t pmd_mkdevmap(pmd_t pmd)
> +{
> +	return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
> +}
>  
>  #define __pmd_to_phys(pmd)	__pte_to_phys(pmd_pte(pmd))
>  #define __phys_to_pmd_val(phys)	__phys_to_pte_val(phys)

Acked-by: Will Deacon <will@kernel.org>

I think Catalin can take this as a fix, although the commit message should
probably be trimmed down a bit to remove the two call traces etc.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] cpufreq: mediatek-cpufreq: Add compatible for MT8516
From: Viresh Kumar @ 2019-08-07  9:05 UTC (permalink / raw)
  To: Fabien Parent
  Cc: linux-pm, rjw, linux-kernel, linux-mediatek, matthias.bgg,
	linux-arm-kernel
In-Reply-To: <20190806095029.4758-1-fparent@baylibre.com>

On 06-08-19, 11:50, Fabien Parent wrote:
> Add the compatible for MT8516 in order to take advantage of the
> MediaTek CPUFreq driver for Mediatek's MT8516 SoC.
> 
> Signed-off-by: Fabien Parent <fparent@baylibre.com>
> ---
>  drivers/cpufreq/mediatek-cpufreq.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
> index f14f3a85f2f7..10bc06f5dd45 100644
> --- a/drivers/cpufreq/mediatek-cpufreq.c
> +++ b/drivers/cpufreq/mediatek-cpufreq.c
> @@ -535,6 +535,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
>  	{ .compatible = "mediatek,mt817x", },
>  	{ .compatible = "mediatek,mt8173", },
>  	{ .compatible = "mediatek,mt8176", },
> +	{ .compatible = "mediatek,mt8516", },
>  
>  	{ }
>  };

Applied. Thanks.

-- 
viresh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] ARM: debug-ll: Add support for r7s9210
From: Geert Uytterhoeven @ 2019-08-07  8:54 UTC (permalink / raw)
  To: Russell King, Simon Horman, Magnus Damm
  Cc: linux-renesas-soc, Chris Brandt, Geert Uytterhoeven,
	linux-arm-kernel

Enable low-level debugging support for RZ/A2M (r7s9210).

The RZA2MEVB board uses either SCIF2 (SDRAM enabled) or SCIF4 (HyperRAM
only) for the serial console.

Note that "SCIFA" serial ports on RZ/A2 SoCs use a compressed register
layout, hence add support for that to renesas-scif.S.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm/Kconfig.debug                | 20 +++++++++++++++++++-
 arch/arm/include/debug/renesas-scif.S |  6 +++++-
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 85710e078afb4878..9fe038aecc553deb 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -924,6 +924,20 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  via SCIF2 on Renesas RZ/A1H (R7S72100).
 
+	config DEBUG_R7S9210_SCIF2
+		bool "Kernel low-level debugging messages via SCIF2 on R7S9210"
+		depends on ARCH_R7S9210
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  via SCIF2 on Renesas RZ/A2M (R7S9210).
+
+	config DEBUG_R7S9210_SCIF4
+		bool "Kernel low-level debugging messages via SCIF4 on R7S9210"
+		depends on ARCH_R7S9210
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  via SCIF4 on Renesas RZ/A2M (R7S9210).
+
 	config DEBUG_RCAR_GEN1_SCIF0
 		bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
 		depends on ARCH_R8A7778
@@ -1537,6 +1551,8 @@ config DEBUG_LL_INCLUDE
 	default "debug/msm.S" if DEBUG_QCOM_UARTDM
 	default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
 	default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
+	default "debug/renesas-scif.S" if DEBUG_R7S9210_SCIF2
+	default "debug/renesas-scif.S" if DEBUG_R7S9210_SCIF4
 	default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
 	default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
 	default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
@@ -1666,7 +1682,8 @@ config DEBUG_UART_PHYS
 	default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
 	default 0xe6e68000 if DEBUG_RCAR_GEN2_SCIF1
 	default 0xe6ee0000 if DEBUG_RCAR_GEN2_SCIF4
-	default 0xe8008000 if DEBUG_R7S72100_SCIF2
+	default 0xe8008000 if DEBUG_R7S72100_SCIF2 || DEBUG_R7S9210_SCIF2
+	default 0xe8009000 if DEBUG_R7S9210_SCIF4
 	default 0xf0000000 if DEBUG_DIGICOLOR_UA0
 	default 0xf0000be0 if ARCH_EBSA110
 	default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE
@@ -1699,6 +1716,7 @@ config DEBUG_UART_PHYS
 		DEBUG_LL_UART_EFM32 || \
 		DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
 		DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
+		DEBUG_R7S9210_SCIF2 || DEBUG_R7S9210_SCIF4 || \
 		DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
 		DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF1 || \
 		DEBUG_RCAR_GEN2_SCIF2 || DEBUG_RCAR_GEN2_SCIF4 || \
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S
index 1c5f795587fc5681..25f06663a9a4e2c1 100644
--- a/arch/arm/include/debug/renesas-scif.S
+++ b/arch/arm/include/debug/renesas-scif.S
@@ -11,7 +11,11 @@
 #define SCIF_PHYS	CONFIG_DEBUG_UART_PHYS
 #define SCIF_VIRT	((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
 
-#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
+#if defined(CONFIG_DEBUG_R7S9210_SCIF2) || defined(CONFIG_DEBUG_R7S9210_SCIF4)
+/* RZ/A2 SCIFA */
+#define FTDR		0x06
+#define FSR		0x08
+#elif CONFIG_DEBUG_UART_PHYS < 0xe6e00000
 /* SCIFA */
 #define FTDR		0x20
 #define FSR		0x14
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Koenig, Christian @ 2019-08-07  8:53 UTC (permalink / raw)
  To: Christoph Hellwig, Zhou1, Tao
  Cc: linux-arm-kernel@lists.infradead.org,
	kernel-build-reports@lists.linaro.org,
	amd-gfx@lists.freedesktop.org, broonie@kernel.org,
	linux-next@vger.kernel.org, Deucher,  Alexander,
	akpm@linux-foundation.org, Li, Dennis, Zhang, Hawking
In-Reply-To: <20190807070834.GA24792@infradead.org>

Am 07.08.19 um 09:08 schrieb Christoph Hellwig:
> On Wed, Aug 07, 2019 at 10:56:40AM +0800, Tao Zhou wrote:
>> readq/writeq are not supported on all architectures
> NAK.  You must not use atomic_* on __iomem (MMIO) memory.

Well then what's the right thing to do here?

Essentially writeq/readq doesn't seems to be available on all 
architectures either.

Regards,
Christian.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 10/41] media/ivtv: convert put_page() to put_user_page*()
From: Hans Verkuil @ 2019-08-07  8:51 UTC (permalink / raw)
  To: john.hubbard, Andrew Morton
  Cc: linux-fbdev, Jan Kara, kvm, Dave Hansen, Dave Chinner, dri-devel,
	linux-mm, sparclinux, Ira Weiny, ceph-devel, devel, rds-devel,
	linux-rdma, x86, amd-gfx, Christoph Hellwig, Jason Gunthorpe,
	xen-devel, devel, linux-media, John Hubbard, intel-gfx,
	linux-block, Jérôme Glisse, linux-rpi-kernel,
	Dan Williams, Mauro Carvalho Chehab, linux-arm-kernel, linux-nfs,
	Andy Walls, netdev, LKML, linux-xfs, linux-crypto, linux-fsdevel
In-Reply-To: <20190807013340.9706-11-jhubbard@nvidia.com>

On 8/7/19 3:33 AM, john.hubbard@gmail.com wrote:
> From: John Hubbard <jhubbard@nvidia.com>
> 
> For pages that were retained via get_user_pages*(), release those pages
> via the new put_user_page*() routines, instead of via put_page() or
> release_pages().
> 
> This is part a tree-wide conversion, as described in commit fc1d8e7cca2d
> ("mm: introduce put_user_page*(), placeholder versions").
> 
> Cc: Andy Walls <awalls@md.metrocast.net>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: linux-media@vger.kernel.org
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>

Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Regards,

	Hans

> ---
>  drivers/media/pci/ivtv/ivtv-udma.c | 14 ++++----------
>  drivers/media/pci/ivtv/ivtv-yuv.c  | 11 +++--------
>  2 files changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
> index 5f8883031c9c..7c7f33c2412b 100644
> --- a/drivers/media/pci/ivtv/ivtv-udma.c
> +++ b/drivers/media/pci/ivtv/ivtv-udma.c
> @@ -92,7 +92,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
>  {
>  	struct ivtv_dma_page_info user_dma;
>  	struct ivtv_user_dma *dma = &itv->udma;
> -	int i, err;
> +	int err;
>  
>  	IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr);
>  
> @@ -119,8 +119,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
>  		IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
>  			   err, user_dma.page_count);
>  		if (err >= 0) {
> -			for (i = 0; i < err; i++)
> -				put_page(dma->map[i]);
> +			put_user_pages(dma->map, err);
>  			return -EINVAL;
>  		}
>  		return err;
> @@ -130,9 +129,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
>  
>  	/* Fill SG List with new values */
>  	if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
> -		for (i = 0; i < dma->page_count; i++) {
> -			put_page(dma->map[i]);
> -		}
> +		put_user_pages(dma->map, dma->page_count);
>  		dma->page_count = 0;
>  		return -ENOMEM;
>  	}
> @@ -153,7 +150,6 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
>  void ivtv_udma_unmap(struct ivtv *itv)
>  {
>  	struct ivtv_user_dma *dma = &itv->udma;
> -	int i;
>  
>  	IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n");
>  
> @@ -170,9 +166,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
>  	ivtv_udma_sync_for_cpu(itv);
>  
>  	/* Release User Pages */
> -	for (i = 0; i < dma->page_count; i++) {
> -		put_page(dma->map[i]);
> -	}
> +	put_user_pages(dma->map, dma->page_count);
>  	dma->page_count = 0;
>  }
>  
> diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
> index cd2fe2d444c0..2c61a11d391d 100644
> --- a/drivers/media/pci/ivtv/ivtv-yuv.c
> +++ b/drivers/media/pci/ivtv/ivtv-yuv.c
> @@ -30,7 +30,6 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
>  	struct yuv_playback_info *yi = &itv->yuv_info;
>  	u8 frame = yi->draw_frame;
>  	struct yuv_frame_info *f = &yi->new_frame_info[frame];
> -	int i;
>  	int y_pages, uv_pages;
>  	unsigned long y_buffer_offset, uv_buffer_offset;
>  	int y_decode_height, uv_decode_height, y_size;
> @@ -81,8 +80,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
>  				 uv_pages, uv_dma.page_count);
>  
>  			if (uv_pages >= 0) {
> -				for (i = 0; i < uv_pages; i++)
> -					put_page(dma->map[y_pages + i]);
> +				put_user_pages(&dma->map[y_pages], uv_pages);
>  				rc = -EFAULT;
>  			} else {
>  				rc = uv_pages;
> @@ -93,8 +91,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
>  				 y_pages, y_dma.page_count);
>  		}
>  		if (y_pages >= 0) {
> -			for (i = 0; i < y_pages; i++)
> -				put_page(dma->map[i]);
> +			put_user_pages(dma->map, y_pages);
>  			/*
>  			 * Inherit the -EFAULT from rc's
>  			 * initialization, but allow it to be
> @@ -112,9 +109,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
>  	/* Fill & map SG List */
>  	if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
>  		IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
> -		for (i = 0; i < dma->page_count; i++) {
> -			put_page(dma->map[i]);
> -		}
> +		put_user_pages(dma->map, dma->page_count);
>  		dma->page_count = 0;
>  		return -ENOMEM;
>  	}
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/2] drm: add cache support for arm64
From: Daniel Vetter @ 2019-08-07  8:48 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Rob Clark, Maxime Ripard, Catalin Marinas, David Airlie,
	Maarten Lankhorst, LKML, dri-devel, Sean Paul, Rob Clark,
	Linux ARM, Greg Kroah-Hartman, Thomas Gleixner, Will Deacon,
	Allison Randal
In-Reply-To: <20190807062545.GF6627@lst.de>

On Wed, Aug 7, 2019 at 8:25 AM Christoph Hellwig <hch@lst.de> wrote:
> On Tue, Aug 06, 2019 at 09:23:51AM -0700, Rob Clark wrote:
> > On Tue, Aug 6, 2019 at 8:50 AM Christoph Hellwig <hch@lst.de> wrote:
> > >
> > > On Tue, Aug 06, 2019 at 07:11:41AM -0700, Rob Clark wrote:
> > > > Agreed that drm_cflush_* isn't a great API.  In this particular case
> > > > (IIUC), I need wb+inv so that there aren't dirty cache lines that drop
> > > > out to memory later, and so that I don't get a cache hit on
> > > > uncached/wc mmap'ing.
> > >
> > > So what is the use case here?  Allocate pages using the page allocator
> > > (or CMA for that matter), and then mmaping them to userspace and never
> > > touching them again from the kernel?
> >
> > Currently, it is pages coming from tmpfs.  Ideally we want pages that
> > are swappable when unpinned.
>
> tmpfs is basically a (complicated) frontend for alloc pages as far
> as page allocation is concerned.
>
> > CPU mappings are *mostly* just mapping to userspace.  There are a few
> > exceptions that are vmap'd (fbcon, and ringbuffer).
>
> And those use the same backend?
>
> > (Eventually I'd like to support pages passed in from userspace.. but
> > that is down the road.)
>
> Eww.  Please talk to the iommu list before starting on that.
>
> > > > Tying it in w/ iommu seems a bit weird to me.. but maybe that is just
> > > > me, I'm certainly willing to consider proposals or to try things and
> > > > see how they work out.
> > >
> > > This was just my through as the fit seems easy.  But maybe you'll
> > > need to explain your use case(s) a bit more so that we can figure out
> > > what a good high level API is.
> >
> > Tying it to iommu_map/unmap would be awkward, as we could need to
> > setup cpu mmap before it ends up mapped to iommu.  And the plan to
> > support per-process pagetables involved creating an iommu_domain per
> > userspace gl context.. some buffers would end up mapped into multiple
> > contexts/iommu_domains.
> >
> > If the cache operation was detached from iommu_map/unmap, then it
> > would seem weird to be part of the iommu API.
> >
> > I guess I'm not entirely sure what you had in mind, but this is why
> > iommu seemed to me like a bad fit.
>
> So back to the question, I'd like to understand your use case (and
> maybe hear from the other drm folks if that is common):

Filling in a bunch more of the use-cases we have in drm. Don't need to
solve them all right away ofc, but whatever direction we're aiming for
should keep these in mind I think.

>  - you allocate pages from shmem (why shmem, btw?  if this is done by
>    other drm drivers how do they guarantee addressability without an
>    iommu?)

We use shmem to get at swappable pages. We generally just assume that
the gpu can get at those pages, but things fall apart in fun ways:
- some setups somehow inject bounce buffers. Some drivers just give
up, others try to allocate a pool of pages with dma_alloc_coherent.
- some devices are misdesigned and can't access as much as the cpu. We
allocate using GFP_DMA32 to fix that.

Also modern gpu apis pretty much assume you can malloc() and then use
that directly with the gpu.

>  - then the memory is either mapped to userspace or vmapped (or even
>    both, althrough the lack of aliasing you mentioned would speak
>    against it) as writecombine (aka arm v6+ normal uncached).  Does
>    the mapping live on until the memory is freed?

Generally we cache mappings forever. Some exceptions for 32bit
userspace excluded, where people expect to be able to use more than
4GB of textures somehow, so we have to recycle old mappings. Obviously
applies less to gpus on socs.

Also, at least i915 also has writeback userspace mmaps, and userspace
doing the cflushing. Also not sure I ever mentioned this, but at least
i915 userspace controls the coherency mode of the device dma directly,
on a per-op granularity. For buffers shared with other processes it
defers to the gpu pagetables, which the kernel controls.

>  - as you mention swapping - how do you guarantee there are no
>    aliases in the kernel direct mapping after the page has been swapped
>    in?

No idea personally, since we can ignore this on x86. I think atm
there's not a huge overlap of gpu drivers doing swapping and running
on something like arm where incompatible aliased mappings are bad.

>  - then the memory is potentially mapped to the iommu.  Is it using
>    a long-living mapping, or does get unmapped/remapped repeatedly?

Again, generally cached for as long as possible, until we run out of
space/memory somewhere.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v6 2/3] drm/mediatek: separate mipi_tx to different file
From: Jitao Shi @ 2019-08-07  8:46 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, linux-pwm,
	David Airlie, Matthias Brugger
  Cc: stonea168, dri-devel, Andy Yan, Ajay Kumar, Vincent Palatin,
	cawa.cheng, bibby.hsieh, ck.hu, Russell King, Thierry Reding,
	devicetree, Jitao Shi, Philipp Zabel, Inki Dae, linux-mediatek,
	yingjoe.chen, eddie.huang, linux-arm-kernel, Rahul Sharma,
	srv_heupstream, linux-kernel, Sascha Hauer, Sean Paul
In-Reply-To: <20190807084645.63738-1-jitao.shi@mediatek.com>

Different IC has different mipi_tx setting of dsi.
This patch separates the mipi_tx hardware relate part for mt8173.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c        | 336 ++----------------
 drivers/gpu/drm/mediatek/mtk_mipi_tx.h        |  48 +++
 drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c | 289 +++++++++++++++
 4 files changed, 359 insertions(+), 315 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mipi_tx.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 82ae49c64221..2c8de1f5a5ee 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -12,6 +12,7 @@ mediatek-drm-y := mtk_disp_color.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
 		  mtk_mipi_tx.o \
+		  mtk_mt8173_mipi_tx.o \
 		  mtk_dpi.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index 1842dc2caae9..77b9a185e970 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -3,292 +3,39 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
-
-#define MIPITX_DSI_CON		0x00
-#define RG_DSI_LDOCORE_EN		BIT(0)
-#define RG_DSI_CKG_LDOOUT_EN		BIT(1)
-#define RG_DSI_BCLK_SEL			(3 << 2)
-#define RG_DSI_LD_IDX_SEL		(7 << 4)
-#define RG_DSI_PHYCLK_SEL		(2 << 8)
-#define RG_DSI_DSICLK_FREQ_SEL		BIT(10)
-#define RG_DSI_LPTX_CLMP_EN		BIT(11)
-
-#define MIPITX_DSI_CLOCK_LANE	0x04
-#define MIPITX_DSI_DATA_LANE0	0x08
-#define MIPITX_DSI_DATA_LANE1	0x0c
-#define MIPITX_DSI_DATA_LANE2	0x10
-#define MIPITX_DSI_DATA_LANE3	0x14
-#define RG_DSI_LNTx_LDOOUT_EN		BIT(0)
-#define RG_DSI_LNTx_CKLANE_EN		BIT(1)
-#define RG_DSI_LNTx_LPTX_IPLUS1		BIT(2)
-#define RG_DSI_LNTx_LPTX_IPLUS2		BIT(3)
-#define RG_DSI_LNTx_LPTX_IMINUS		BIT(4)
-#define RG_DSI_LNTx_LPCD_IPLUS		BIT(5)
-#define RG_DSI_LNTx_LPCD_IMINUS		BIT(6)
-#define RG_DSI_LNTx_RT_CODE		(0xf << 8)
-
-#define MIPITX_DSI_TOP_CON	0x40
-#define RG_DSI_LNT_INTR_EN		BIT(0)
-#define RG_DSI_LNT_HS_BIAS_EN		BIT(1)
-#define RG_DSI_LNT_IMP_CAL_EN		BIT(2)
-#define RG_DSI_LNT_TESTMODE_EN		BIT(3)
-#define RG_DSI_LNT_IMP_CAL_CODE		(0xf << 4)
-#define RG_DSI_LNT_AIO_SEL		(7 << 8)
-#define RG_DSI_PAD_TIE_LOW_EN		BIT(11)
-#define RG_DSI_DEBUG_INPUT_EN		BIT(12)
-#define RG_DSI_PRESERVE			(7 << 13)
-
-#define MIPITX_DSI_BG_CON	0x44
-#define RG_DSI_BG_CORE_EN		BIT(0)
-#define RG_DSI_BG_CKEN			BIT(1)
-#define RG_DSI_BG_DIV			(0x3 << 2)
-#define RG_DSI_BG_FAST_CHARGE		BIT(4)
-#define RG_DSI_VOUT_MSK			(0x3ffff << 5)
-#define RG_DSI_V12_SEL			(7 << 5)
-#define RG_DSI_V10_SEL			(7 << 8)
-#define RG_DSI_V072_SEL			(7 << 11)
-#define RG_DSI_V04_SEL			(7 << 14)
-#define RG_DSI_V032_SEL			(7 << 17)
-#define RG_DSI_V02_SEL			(7 << 20)
-#define RG_DSI_BG_R1_TRIM		(0xf << 24)
-#define RG_DSI_BG_R2_TRIM		(0xf << 28)
-
-#define MIPITX_DSI_PLL_CON0	0x50
-#define RG_DSI_MPPLL_PLL_EN		BIT(0)
-#define RG_DSI_MPPLL_DIV_MSK		(0x1ff << 1)
-#define RG_DSI_MPPLL_PREDIV		(3 << 1)
-#define RG_DSI_MPPLL_TXDIV0		(3 << 3)
-#define RG_DSI_MPPLL_TXDIV1		(3 << 5)
-#define RG_DSI_MPPLL_POSDIV		(7 << 7)
-#define RG_DSI_MPPLL_MONVC_EN		BIT(10)
-#define RG_DSI_MPPLL_MONREF_EN		BIT(11)
-#define RG_DSI_MPPLL_VOD_EN		BIT(12)
-
-#define MIPITX_DSI_PLL_CON1	0x54
-#define RG_DSI_MPPLL_SDM_FRA_EN		BIT(0)
-#define RG_DSI_MPPLL_SDM_SSC_PH_INIT	BIT(1)
-#define RG_DSI_MPPLL_SDM_SSC_EN		BIT(2)
-#define RG_DSI_MPPLL_SDM_SSC_PRD	(0xffff << 16)
-
-#define MIPITX_DSI_PLL_CON2	0x58
-
-#define MIPITX_DSI_PLL_TOP	0x64
-#define RG_DSI_MPPLL_PRESERVE		(0xff << 8)
-
-#define MIPITX_DSI_PLL_PWR	0x68
-#define RG_DSI_MPPLL_SDM_PWR_ON		BIT(0)
-#define RG_DSI_MPPLL_SDM_ISO_EN		BIT(1)
-#define RG_DSI_MPPLL_SDM_PWR_ACK	BIT(8)
-
-#define MIPITX_DSI_SW_CTRL	0x80
-#define SW_CTRL_EN			BIT(0)
-
-#define MIPITX_DSI_SW_CTRL_CON0	0x84
-#define SW_LNTC_LPTX_PRE_OE		BIT(0)
-#define SW_LNTC_LPTX_OE			BIT(1)
-#define SW_LNTC_LPTX_P			BIT(2)
-#define SW_LNTC_LPTX_N			BIT(3)
-#define SW_LNTC_HSTX_PRE_OE		BIT(4)
-#define SW_LNTC_HSTX_OE			BIT(5)
-#define SW_LNTC_HSTX_ZEROCLK		BIT(6)
-#define SW_LNT0_LPTX_PRE_OE		BIT(7)
-#define SW_LNT0_LPTX_OE			BIT(8)
-#define SW_LNT0_LPTX_P			BIT(9)
-#define SW_LNT0_LPTX_N			BIT(10)
-#define SW_LNT0_HSTX_PRE_OE		BIT(11)
-#define SW_LNT0_HSTX_OE			BIT(12)
-#define SW_LNT0_LPRX_EN			BIT(13)
-#define SW_LNT1_LPTX_PRE_OE		BIT(14)
-#define SW_LNT1_LPTX_OE			BIT(15)
-#define SW_LNT1_LPTX_P			BIT(16)
-#define SW_LNT1_LPTX_N			BIT(17)
-#define SW_LNT1_HSTX_PRE_OE		BIT(18)
-#define SW_LNT1_HSTX_OE			BIT(19)
-#define SW_LNT2_LPTX_PRE_OE		BIT(20)
-#define SW_LNT2_LPTX_OE			BIT(21)
-#define SW_LNT2_LPTX_P			BIT(22)
-#define SW_LNT2_LPTX_N			BIT(23)
-#define SW_LNT2_HSTX_PRE_OE		BIT(24)
-#define SW_LNT2_HSTX_OE			BIT(25)
-
-struct mtk_mipitx_data {
-	const u32 mppll_preserve;
-};
-
-struct mtk_mipi_tx {
-	struct device *dev;
-	void __iomem *regs;
-	u32 data_rate;
-	const struct mtk_mipitx_data *driver_data;
-	struct clk_hw pll_hw;
-	struct clk *pll;
-};
+#include "mtk_mipi_tx.h"
 
-static inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
+inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
 {
 	return container_of(hw, struct mtk_mipi_tx, pll_hw);
 }
 
-static void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-				   u32 bits)
+void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
+			    u32 bits)
 {
 	u32 temp = readl(mipi_tx->regs + offset);
 
 	writel(temp & ~bits, mipi_tx->regs + offset);
 }
 
-static void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-				 u32 bits)
+void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
+			  u32 bits)
 {
 	u32 temp = readl(mipi_tx->regs + offset);
 
 	writel(temp | bits, mipi_tx->regs + offset);
 }
 
-static void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-				    u32 mask, u32 data)
+void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
+			     u32 mask, u32 data)
 {
 	u32 temp = readl(mipi_tx->regs + offset);
 
 	writel((temp & ~mask) | (data & mask), mipi_tx->regs + offset);
 }
 
-static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
-{
-	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
-	u8 txdiv, txdiv0, txdiv1;
-	u64 pcw;
-
-	dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
-
-	if (mipi_tx->data_rate >= 500000000) {
-		txdiv = 1;
-		txdiv0 = 0;
-		txdiv1 = 0;
-	} else if (mipi_tx->data_rate >= 250000000) {
-		txdiv = 2;
-		txdiv0 = 1;
-		txdiv1 = 0;
-	} else if (mipi_tx->data_rate >= 125000000) {
-		txdiv = 4;
-		txdiv0 = 2;
-		txdiv1 = 0;
-	} else if (mipi_tx->data_rate > 62000000) {
-		txdiv = 8;
-		txdiv0 = 2;
-		txdiv1 = 1;
-	} else if (mipi_tx->data_rate >= 50000000) {
-		txdiv = 16;
-		txdiv0 = 2;
-		txdiv1 = 2;
-	} else {
-		return -EINVAL;
-	}
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON,
-				RG_DSI_VOUT_MSK |
-				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN,
-				(4 << 20) | (4 << 17) | (4 << 14) |
-				(4 << 11) | (4 << 8) | (4 << 5) |
-				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
-
-	usleep_range(30, 100);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON,
-				RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN,
-				(8 << 4) | RG_DSI_LNT_HS_BIAS_EN);
-
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON,
-			     RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
-				RG_DSI_MPPLL_SDM_PWR_ON |
-				RG_DSI_MPPLL_SDM_ISO_EN,
-				RG_DSI_MPPLL_SDM_PWR_ON);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
-			       RG_DSI_MPPLL_PLL_EN);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
-				RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 |
-				RG_DSI_MPPLL_PREDIV,
-				(txdiv0 << 3) | (txdiv1 << 5));
-
-	/*
-	 * PLL PCW config
-	 * PCW bit 24~30 = integer part of pcw
-	 * PCW bit 0~23 = fractional part of pcw
-	 * pcw = data_Rate*4*txdiv/(Ref_clk*2);
-	 * Post DIV =4, so need data_Rate*4
-	 * Ref_clk is 26MHz
-	 */
-	pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24,
-		      26000000);
-	writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2);
-
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
-			     RG_DSI_MPPLL_SDM_FRA_EN);
-
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);
-
-	usleep_range(20, 100);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
-			       RG_DSI_MPPLL_SDM_SSC_EN);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
-				RG_DSI_MPPLL_PRESERVE,
-				mipi_tx->driver_data->mppll_preserve);
-
-	return 0;
-}
-
-static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
-{
-	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
-
-	dev_dbg(mipi_tx->dev, "unprepare\n");
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
-			       RG_DSI_MPPLL_PLL_EN);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
-				RG_DSI_MPPLL_PRESERVE, 0);
-
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
-				RG_DSI_MPPLL_SDM_ISO_EN |
-				RG_DSI_MPPLL_SDM_PWR_ON,
-				RG_DSI_MPPLL_SDM_ISO_EN);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
-			       RG_DSI_LNT_HS_BIAS_EN);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON,
-			       RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON,
-			       RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
-			       RG_DSI_MPPLL_DIV_MSK);
-}
-
-static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *prate)
-{
-	return clamp_val(rate, 50000000, 1250000000);
-}
-
-static int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long parent_rate)
+int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
 {
 	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
 
@@ -299,37 +46,14 @@ static int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
-static unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
-						 unsigned long parent_rate)
+unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
 {
 	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
 
 	return mipi_tx->data_rate;
 }
 
-static const struct clk_ops mtk_mipi_tx_pll_ops = {
-	.prepare = mtk_mipi_tx_pll_prepare,
-	.unprepare = mtk_mipi_tx_pll_unprepare,
-	.round_rate = mtk_mipi_tx_pll_round_rate,
-	.set_rate = mtk_mipi_tx_pll_set_rate,
-	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
-};
-
-static int mtk_mipi_tx_power_on_signal(struct phy *phy)
-{
-	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
-	u32 reg;
-
-	for (reg = MIPITX_DSI_CLOCK_LANE;
-	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
-		mtk_mipi_tx_set_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
-
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
-			       RG_DSI_PAD_TIE_LOW_EN);
-
-	return 0;
-}
-
 static int mtk_mipi_tx_power_on(struct phy *phy)
 {
 	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
@@ -341,30 +65,16 @@ static int mtk_mipi_tx_power_on(struct phy *phy)
 		return ret;
 
 	/* Enable DSI Lane LDO outputs, disable pad tie low */
-	mtk_mipi_tx_power_on_signal(phy);
-
+	mipi_tx->driver_data->mipi_tx_enable_signal(phy);
 	return 0;
 }
 
-static void mtk_mipi_tx_power_off_signal(struct phy *phy)
-{
-	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
-	u32 reg;
-
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
-			     RG_DSI_PAD_TIE_LOW_EN);
-
-	for (reg = MIPITX_DSI_CLOCK_LANE;
-	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
-		mtk_mipi_tx_clear_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
-}
-
 static int mtk_mipi_tx_power_off(struct phy *phy)
 {
 	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
 
 	/* Enable pad tie low, disable DSI Lane LDO outputs */
-	mtk_mipi_tx_power_off_signal(phy);
+	mipi_tx->driver_data->mipi_tx_disable_signal(phy);
 
 	/* Disable PLL and power down core */
 	clk_disable_unprepare(mipi_tx->pll);
@@ -383,10 +93,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct mtk_mipi_tx *mipi_tx;
 	struct resource *mem;
-	struct clk *ref_clk;
 	const char *ref_clk_name;
+	struct clk *ref_clk;
 	struct clk_init_data clk_init = {
-		.ops = &mtk_mipi_tx_pll_ops,
 		.num_parents = 1,
 		.parent_names = (const char * const *)&ref_clk_name,
 		.flags = CLK_SET_RATE_GATE,
@@ -400,6 +109,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
+
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mipi_tx->regs = devm_ioremap_resource(dev, mem);
 	if (IS_ERR(mipi_tx->regs)) {
@@ -414,6 +124,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		dev_err(dev, "Failed to get reference clock: %d\n", ret);
 		return ret;
 	}
+
 	ref_clk_name = __clk_get_name(ref_clk);
 
 	ret = of_property_read_string(dev->of_node, "clock-output-names",
@@ -423,6 +134,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops;
+
 	mipi_tx->pll_hw.init = &clk_init;
 	mipi_tx->pll = devm_clk_register(dev, &mipi_tx->pll_hw);
 	if (IS_ERR(mipi_tx->pll)) {
@@ -457,20 +170,12 @@ static int mtk_mipi_tx_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct mtk_mipitx_data mt2701_mipitx_data = {
-	.mppll_preserve = (3 << 8)
-};
-
-static const struct mtk_mipitx_data mt8173_mipitx_data = {
-	.mppll_preserve = (0 << 8)
-};
-
 static const struct of_device_id mtk_mipi_tx_match[] = {
 	{ .compatible = "mediatek,mt2701-mipi-tx",
 	  .data = &mt2701_mipitx_data },
 	{ .compatible = "mediatek,mt8173-mipi-tx",
 	  .data = &mt8173_mipitx_data },
-	{},
+	{ },
 };
 
 struct platform_driver mtk_mipi_tx_driver = {
@@ -481,3 +186,4 @@ struct platform_driver mtk_mipi_tx_driver = {
 		.of_match_table = mtk_mipi_tx_match,
 	},
 };
+
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.h b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h
new file mode 100644
index 000000000000..4f905313564f
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Jitao Shi <jitao.shi@mediatek.com>
+ */
+
+#ifndef _MTK_MIPI_TX_H
+#define _MTK_MIPI_TX_H
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+struct mtk_mipitx_data {
+	const u32 mppll_preserve;
+	const struct clk_ops *mipi_tx_clk_ops;
+	void (*mipi_tx_enable_signal)(struct phy *phy);
+	void (*mipi_tx_disable_signal)(struct phy *phy);
+};
+
+struct mtk_mipi_tx {
+	struct device *dev;
+	void __iomem *regs;
+	u32 data_rate;
+	const struct mtk_mipitx_data *driver_data;
+	struct clk_hw pll_hw;
+	struct clk *pll;
+};
+
+struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw);
+void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits);
+void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits);
+void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 mask,
+			     u32 data);
+int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate);
+unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate);
+
+extern const struct mtk_mipitx_data mt2701_mipitx_data;
+extern const struct mtk_mipitx_data mt8173_mipitx_data;
+
+#endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c
new file mode 100644
index 000000000000..95ef0c5252b9
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: jitao.shi <jitao.shi@mediatek.com>
+ */
+
+#include "mtk_mipi_tx.h"
+
+#define MIPITX_DSI_CON		0x00
+#define RG_DSI_LDOCORE_EN		BIT(0)
+#define RG_DSI_CKG_LDOOUT_EN		BIT(1)
+#define RG_DSI_BCLK_SEL			(3 << 2)
+#define RG_DSI_LD_IDX_SEL		(7 << 4)
+#define RG_DSI_PHYCLK_SEL		(2 << 8)
+#define RG_DSI_DSICLK_FREQ_SEL		BIT(10)
+#define RG_DSI_LPTX_CLMP_EN		BIT(11)
+
+#define MIPITX_DSI_CLOCK_LANE	0x04
+#define MIPITX_DSI_DATA_LANE0	0x08
+#define MIPITX_DSI_DATA_LANE1	0x0c
+#define MIPITX_DSI_DATA_LANE2	0x10
+#define MIPITX_DSI_DATA_LANE3	0x14
+#define RG_DSI_LNTx_LDOOUT_EN		BIT(0)
+#define RG_DSI_LNTx_CKLANE_EN		BIT(1)
+#define RG_DSI_LNTx_LPTX_IPLUS1		BIT(2)
+#define RG_DSI_LNTx_LPTX_IPLUS2		BIT(3)
+#define RG_DSI_LNTx_LPTX_IMINUS		BIT(4)
+#define RG_DSI_LNTx_LPCD_IPLUS		BIT(5)
+#define RG_DSI_LNTx_LPCD_IMINUS		BIT(6)
+#define RG_DSI_LNTx_RT_CODE		(0xf << 8)
+
+#define MIPITX_DSI_TOP_CON	0x40
+#define RG_DSI_LNT_INTR_EN		BIT(0)
+#define RG_DSI_LNT_HS_BIAS_EN		BIT(1)
+#define RG_DSI_LNT_IMP_CAL_EN		BIT(2)
+#define RG_DSI_LNT_TESTMODE_EN		BIT(3)
+#define RG_DSI_LNT_IMP_CAL_CODE		(0xf << 4)
+#define RG_DSI_LNT_AIO_SEL		(7 << 8)
+#define RG_DSI_PAD_TIE_LOW_EN		BIT(11)
+#define RG_DSI_DEBUG_INPUT_EN		BIT(12)
+#define RG_DSI_PRESERVE			(7 << 13)
+
+#define MIPITX_DSI_BG_CON	0x44
+#define RG_DSI_BG_CORE_EN		BIT(0)
+#define RG_DSI_BG_CKEN			BIT(1)
+#define RG_DSI_BG_DIV			(0x3 << 2)
+#define RG_DSI_BG_FAST_CHARGE		BIT(4)
+#define RG_DSI_VOUT_MSK			(0x3ffff << 5)
+#define RG_DSI_V12_SEL			(7 << 5)
+#define RG_DSI_V10_SEL			(7 << 8)
+#define RG_DSI_V072_SEL			(7 << 11)
+#define RG_DSI_V04_SEL			(7 << 14)
+#define RG_DSI_V032_SEL			(7 << 17)
+#define RG_DSI_V02_SEL			(7 << 20)
+#define RG_DSI_BG_R1_TRIM		(0xf << 24)
+#define RG_DSI_BG_R2_TRIM		(0xf << 28)
+
+#define MIPITX_DSI_PLL_CON0	0x50
+#define RG_DSI_MPPLL_PLL_EN		BIT(0)
+#define RG_DSI_MPPLL_DIV_MSK		(0x1ff << 1)
+#define RG_DSI_MPPLL_PREDIV		(3 << 1)
+#define RG_DSI_MPPLL_TXDIV0		(3 << 3)
+#define RG_DSI_MPPLL_TXDIV1		(3 << 5)
+#define RG_DSI_MPPLL_POSDIV		(7 << 7)
+#define RG_DSI_MPPLL_MONVC_EN		BIT(10)
+#define RG_DSI_MPPLL_MONREF_EN		BIT(11)
+#define RG_DSI_MPPLL_VOD_EN		BIT(12)
+
+#define MIPITX_DSI_PLL_CON1	0x54
+#define RG_DSI_MPPLL_SDM_FRA_EN		BIT(0)
+#define RG_DSI_MPPLL_SDM_SSC_PH_INIT	BIT(1)
+#define RG_DSI_MPPLL_SDM_SSC_EN		BIT(2)
+#define RG_DSI_MPPLL_SDM_SSC_PRD	(0xffff << 16)
+
+#define MIPITX_DSI_PLL_CON2	0x58
+
+#define MIPITX_DSI_PLL_TOP	0x64
+#define RG_DSI_MPPLL_PRESERVE		(0xff << 8)
+
+#define MIPITX_DSI_PLL_PWR	0x68
+#define RG_DSI_MPPLL_SDM_PWR_ON		BIT(0)
+#define RG_DSI_MPPLL_SDM_ISO_EN		BIT(1)
+#define RG_DSI_MPPLL_SDM_PWR_ACK	BIT(8)
+
+#define MIPITX_DSI_SW_CTRL	0x80
+#define SW_CTRL_EN			BIT(0)
+
+#define MIPITX_DSI_SW_CTRL_CON0	0x84
+#define SW_LNTC_LPTX_PRE_OE		BIT(0)
+#define SW_LNTC_LPTX_OE			BIT(1)
+#define SW_LNTC_LPTX_P			BIT(2)
+#define SW_LNTC_LPTX_N			BIT(3)
+#define SW_LNTC_HSTX_PRE_OE		BIT(4)
+#define SW_LNTC_HSTX_OE			BIT(5)
+#define SW_LNTC_HSTX_ZEROCLK		BIT(6)
+#define SW_LNT0_LPTX_PRE_OE		BIT(7)
+#define SW_LNT0_LPTX_OE			BIT(8)
+#define SW_LNT0_LPTX_P			BIT(9)
+#define SW_LNT0_LPTX_N			BIT(10)
+#define SW_LNT0_HSTX_PRE_OE		BIT(11)
+#define SW_LNT0_HSTX_OE			BIT(12)
+#define SW_LNT0_LPRX_EN			BIT(13)
+#define SW_LNT1_LPTX_PRE_OE		BIT(14)
+#define SW_LNT1_LPTX_OE			BIT(15)
+#define SW_LNT1_LPTX_P			BIT(16)
+#define SW_LNT1_LPTX_N			BIT(17)
+#define SW_LNT1_HSTX_PRE_OE		BIT(18)
+#define SW_LNT1_HSTX_OE			BIT(19)
+#define SW_LNT2_LPTX_PRE_OE		BIT(20)
+#define SW_LNT2_LPTX_OE			BIT(21)
+#define SW_LNT2_LPTX_P			BIT(22)
+#define SW_LNT2_LPTX_N			BIT(23)
+#define SW_LNT2_HSTX_PRE_OE		BIT(24)
+#define SW_LNT2_HSTX_OE			BIT(25)
+
+static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
+{
+	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+	u8 txdiv, txdiv0, txdiv1;
+	u64 pcw;
+
+	dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
+
+	if (mipi_tx->data_rate >= 500000000) {
+		txdiv = 1;
+		txdiv0 = 0;
+		txdiv1 = 0;
+	} else if (mipi_tx->data_rate >= 250000000) {
+		txdiv = 2;
+		txdiv0 = 1;
+		txdiv1 = 0;
+	} else if (mipi_tx->data_rate >= 125000000) {
+		txdiv = 4;
+		txdiv0 = 2;
+		txdiv1 = 0;
+	} else if (mipi_tx->data_rate > 62000000) {
+		txdiv = 8;
+		txdiv0 = 2;
+		txdiv1 = 1;
+	} else if (mipi_tx->data_rate >= 50000000) {
+		txdiv = 16;
+		txdiv0 = 2;
+		txdiv1 = 2;
+	} else {
+		return -EINVAL;
+	}
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON,
+				RG_DSI_VOUT_MSK |
+				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN,
+				(4 << 20) | (4 << 17) | (4 << 14) |
+				(4 << 11) | (4 << 8) | (4 << 5) |
+				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
+
+	usleep_range(30, 100);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+				RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN,
+				(8 << 4) | RG_DSI_LNT_HS_BIAS_EN);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON,
+			     RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
+				RG_DSI_MPPLL_SDM_PWR_ON |
+				RG_DSI_MPPLL_SDM_ISO_EN,
+				RG_DSI_MPPLL_SDM_PWR_ON);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+			       RG_DSI_MPPLL_PLL_EN);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+				RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 |
+				RG_DSI_MPPLL_PREDIV,
+				(txdiv0 << 3) | (txdiv1 << 5));
+
+	/*
+	 * PLL PCW config
+	 * PCW bit 24~30 = integer part of pcw
+	 * PCW bit 0~23 = fractional part of pcw
+	 * pcw = data_Rate*4*txdiv/(Ref_clk*2);
+	 * Post DIV =4, so need data_Rate*4
+	 * Ref_clk is 26MHz
+	 */
+	pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24,
+		      26000000);
+	writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
+			     RG_DSI_MPPLL_SDM_FRA_EN);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);
+
+	usleep_range(20, 100);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
+			       RG_DSI_MPPLL_SDM_SSC_EN);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
+				RG_DSI_MPPLL_PRESERVE,
+				mipi_tx->driver_data->mppll_preserve);
+
+	return 0;
+}
+
+static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
+{
+	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+
+	dev_dbg(mipi_tx->dev, "unprepare\n");
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+			       RG_DSI_MPPLL_PLL_EN);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
+				RG_DSI_MPPLL_PRESERVE, 0);
+
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
+				RG_DSI_MPPLL_SDM_ISO_EN |
+				RG_DSI_MPPLL_SDM_PWR_ON,
+				RG_DSI_MPPLL_SDM_ISO_EN);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+			       RG_DSI_LNT_HS_BIAS_EN);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON,
+			       RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON,
+			       RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+			       RG_DSI_MPPLL_DIV_MSK);
+}
+
+static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *prate)
+{
+	return clamp_val(rate, 50000000, 1250000000);
+}
+
+static const struct clk_ops mtk_mipi_tx_pll_ops = {
+	.prepare = mtk_mipi_tx_pll_prepare,
+	.unprepare = mtk_mipi_tx_pll_unprepare,
+	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.set_rate = mtk_mipi_tx_pll_set_rate,
+	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
+};
+
+static void mtk_mipi_tx_power_on_signal(struct phy *phy)
+{
+	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+	u32 reg;
+
+	for (reg = MIPITX_DSI_CLOCK_LANE;
+	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
+		mtk_mipi_tx_set_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+			       RG_DSI_PAD_TIE_LOW_EN);
+}
+
+static void mtk_mipi_tx_power_off_signal(struct phy *phy)
+{
+	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+	u32 reg;
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+			     RG_DSI_PAD_TIE_LOW_EN);
+
+	for (reg = MIPITX_DSI_CLOCK_LANE;
+	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
+		mtk_mipi_tx_clear_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
+}
+
+const struct mtk_mipitx_data mt2701_mipitx_data = {
+	.mppll_preserve = (3 << 8),
+	.mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops,
+	.mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal,
+	.mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal,
+};
+
+const struct mtk_mipitx_data mt8173_mipitx_data = {
+	.mppll_preserve = (0 << 8),
+	.mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops,
+	.mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal,
+	.mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal,
+};
+
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v6 3/3] drm/mediatek: add mipi_tx driver for mt8183
From: Jitao Shi @ 2019-08-07  8:46 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, linux-pwm,
	David Airlie, Matthias Brugger
  Cc: stonea168, dri-devel, Andy Yan, Ajay Kumar, Vincent Palatin,
	cawa.cheng, bibby.hsieh, ck.hu, Russell King, Thierry Reding,
	devicetree, Jitao Shi, Philipp Zabel, Inki Dae, linux-mediatek,
	yingjoe.chen, eddie.huang, linux-arm-kernel, Rahul Sharma,
	srv_heupstream, linux-kernel, Sascha Hauer, Sean Paul
In-Reply-To: <20190807084645.63738-1-jitao.shi@mediatek.com>

This patch add mt8183 mipi_tx driver.
And also support other chips that use the same binding and driver.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c        |   2 +
 drivers/gpu/drm/mediatek/mtk_mipi_tx.h        |   1 +
 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 150 ++++++++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 2c8de1f5a5ee..8067a4be8311 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,6 +13,7 @@ mediatek-drm-y := mtk_disp_color.o \
 		  mtk_dsi.o \
 		  mtk_mipi_tx.o \
 		  mtk_mt8173_mipi_tx.o \
+		  mtk_mt8183_mipi_tx.o \
 		  mtk_dpi.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index 77b9a185e970..e4d34484ecc8 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -175,6 +175,8 @@ static const struct of_device_id mtk_mipi_tx_match[] = {
 	  .data = &mt2701_mipitx_data },
 	{ .compatible = "mediatek,mt8173-mipi-tx",
 	  .data = &mt8173_mipitx_data },
+	{ .compatible = "mediatek,mt8183-mipi-tx",
+	  .data = &mt8183_mipitx_data },
 	{ },
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.h b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h
index 4f905313564f..413f35d86219 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.h
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h
@@ -44,5 +44,6 @@ unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
 
 extern const struct mtk_mipitx_data mt2701_mipitx_data;
 extern const struct mtk_mipitx_data mt8173_mipitx_data;
+extern const struct mtk_mipitx_data mt8183_mipitx_data;
 
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c
new file mode 100644
index 000000000000..db13ebdbe262
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: jitao.shi <jitao.shi@mediatek.com>
+ */
+
+#include "mtk_mipi_tx.h"
+
+#define MIPITX_LANE_CON		0x000c
+#define RG_DSI_CPHY_T1DRV_EN		BIT(0)
+#define RG_DSI_ANA_CK_SEL		BIT(1)
+#define RG_DSI_PHY_CK_SEL		BIT(2)
+#define RG_DSI_CPHY_EN			BIT(3)
+#define RG_DSI_PHYCK_INV_EN		BIT(4)
+#define RG_DSI_PWR04_EN			BIT(5)
+#define RG_DSI_BG_LPF_EN		BIT(6)
+#define RG_DSI_BG_CORE_EN		BIT(7)
+#define RG_DSI_PAD_TIEL_SEL		BIT(8)
+
+#define MIPITX_PLL_PWR	0x0028
+#define MIPITX_PLL_CON0	0x002c
+#define MIPITX_PLL_CON1	0x0030
+#define MIPITX_PLL_CON2	0x0034
+#define MIPITX_PLL_CON3	0x0038
+#define MIPITX_PLL_CON4	0x003c
+#define RG_DSI_PLL_IBIAS		(3 << 10)
+
+#define MIPITX_D2_SW_CTL_EN	0x0144
+#define MIPITX_D0_SW_CTL_EN	0x0244
+#define MIPITX_CK_CKMODE_EN	0x0328
+#define DSI_CK_CKMODE_EN		BIT(0)
+#define MIPITX_CK_SW_CTL_EN	0x0344
+#define MIPITX_D1_SW_CTL_EN	0x0444
+#define MIPITX_D3_SW_CTL_EN	0x0544
+#define DSI_SW_CTL_EN			BIT(0)
+#define AD_DSI_PLL_SDM_PWR_ON		BIT(0)
+#define AD_DSI_PLL_SDM_ISO_EN		BIT(1)
+
+#define RG_DSI_PLL_EN			BIT(4)
+#define RG_DSI_PLL_POSDIV		(0x7 << 8)
+
+static int mtk_mipi_tx_pll_enable(struct clk_hw *hw)
+{
+	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+	unsigned int txdiv, txdiv0;
+	u64 pcw;
+
+	dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate);
+
+	if (mipi_tx->data_rate >= 2000000000) {
+		txdiv = 1;
+		txdiv0 = 0;
+	} else if (mipi_tx->data_rate >= 1000000000) {
+		txdiv = 2;
+		txdiv0 = 1;
+	} else if (mipi_tx->data_rate >= 500000000) {
+		txdiv = 4;
+		txdiv0 = 2;
+	} else if (mipi_tx->data_rate > 250000000) {
+		txdiv = 8;
+		txdiv0 = 3;
+	} else if (mipi_tx->data_rate >= 125000000) {
+		txdiv = 16;
+		txdiv0 = 4;
+	} else {
+		return -EINVAL;
+	}
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+	udelay(1);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+	pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000);
+	writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0);
+	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV,
+				txdiv0 << 8);
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+
+	return 0;
+}
+
+static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
+{
+	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+}
+
+static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *prate)
+{
+	return clamp_val(rate, 50000000, 1600000000);
+}
+
+static const struct clk_ops mtk_mipi_tx_pll_ops = {
+	.enable = mtk_mipi_tx_pll_enable,
+	.disable = mtk_mipi_tx_pll_disable,
+	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.set_rate = mtk_mipi_tx_pll_set_rate,
+	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
+};
+
+static void mtk_mipi_tx_power_on_signal(struct phy *phy)
+{
+	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+
+	/* BG_LPF_EN / BG_CORE_EN */
+	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
+	       mipi_tx->regs + MIPITX_LANE_CON);
+	usleep_range(30, 100);
+	writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN,
+	       mipi_tx->regs + MIPITX_LANE_CON);
+
+	/* Switch OFF each Lane */
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
+}
+
+static void mtk_mipi_tx_power_off_signal(struct phy *phy)
+{
+	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+
+	/* Switch ON each Lane */
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+
+	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
+	       mipi_tx->regs + MIPITX_LANE_CON);
+	writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON);
+}
+
+const struct mtk_mipitx_data mt8183_mipitx_data = {
+	.mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops,
+	.mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal,
+	.mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal,
+};
+
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v6 0/3] Support mipitx for mt8183
From: Jitao Shi @ 2019-08-07  8:46 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, linux-pwm,
	David Airlie, Matthias Brugger
  Cc: stonea168, dri-devel, Andy Yan, Ajay Kumar, Vincent Palatin,
	cawa.cheng, bibby.hsieh, ck.hu, Russell King, Thierry Reding,
	devicetree, Jitao Shi, Philipp Zabel, Inki Dae, linux-mediatek,
	yingjoe.chen, eddie.huang, linux-arm-kernel, Rahul Sharma,
	srv_heupstream, linux-kernel, Sascha Hauer, Sean Paul

Change since v5:
 - remove mipi_tx->ref_clk
 - remove mt8183 pll prepare unprepare

Change since v4:
 - fine tune the mipi_tx->ref_clk and mipi_tx->pll sequence
   1. Prepare mipi_tx->ref_clk
   2. Prepare mipi_tx->pll
   3. Enable mipi_tx->ref_clk
   4. Enable mipi_tx->pll

Changes since v3:
 - turn off PLL before setting PLL parameters.

Changes since v2:
 - update Acked-by: Rob Herring <robh@kernel.org>
 - update mt8183 max bit rate support

Changes since v1:
 - update dt-bindings document for mt8183 mipitx.
 - remove mtk_mipitx_clk_get_ops and assign clk_ops in probe.
 - fix the lincence
 - remove txdiv1 from mtk_mipi_tx_pll_prepare

Jitao Shi (3):
  dt-bindings: display: mediatek: update dsi supported chips
  drm/mediatek: separate mipi_tx to different file
  drm/mediatek: add mipi_tx driver for mt8183

 .../display/mediatek/mediatek,dsi.txt         |   4 +-
 drivers/gpu/drm/mediatek/Makefile             |   2 +
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c        | 338 ++----------------
 drivers/gpu/drm/mediatek/mtk_mipi_tx.h        |  49 +++
 drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c | 289 +++++++++++++++
 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 150 ++++++++
 6 files changed, 515 insertions(+), 317 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mipi_tx.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c

-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v6 1/3] dt-bindings: display: mediatek: update dsi supported chips
From: Jitao Shi @ 2019-08-07  8:46 UTC (permalink / raw)
  To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, linux-pwm,
	David Airlie, Matthias Brugger
  Cc: stonea168, dri-devel, Andy Yan, Ajay Kumar, Rob Herring,
	Vincent Palatin, cawa.cheng, bibby.hsieh, ck.hu, Russell King,
	Thierry Reding, devicetree, Jitao Shi, Philipp Zabel, Inki Dae,
	linux-mediatek, yingjoe.chen, eddie.huang, linux-arm-kernel,
	Rahul Sharma, srv_heupstream, linux-kernel, Sascha Hauer,
	Sean Paul
In-Reply-To: <20190807084645.63738-1-jitao.shi@mediatek.com>

Update device tree binding documentation for the dsi for
Mediatek MT8183 SoCs.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/display/mediatek/mediatek,dsi.txt     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
index fadf327c7cdf..a19a6cc375ed 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
@@ -7,7 +7,7 @@ channel output.
 
 Required properties:
 - compatible: "mediatek,<chip>-dsi"
-  the supported chips are mt2701 and mt8173.
+  the supported chips are mt2701, mt8173 and mt8183.
 - reg: Physical base address and length of the controller's registers
 - interrupts: The interrupt signal from the function block.
 - clocks: device clocks
@@ -26,7 +26,7 @@ The MIPI TX configuration module controls the MIPI D-PHY.
 
 Required properties:
 - compatible: "mediatek,<chip>-mipi-tx"
-  the supported chips are mt2701 and mt8173.
+  the supported chips are mt2701, mt8173 and mt8183.
 - reg: Physical base address and length of the controller's registers
 - clocks: PLL reference clock
 - clock-output-names: name of the output clock line to the DSI encoder
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox