* [PATCH v3 2/3] powerpc/reloc64: add support for 32-bit CRC pseudo-symbols
From: Michael Ellerman @ 2016-11-25 11:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477585631-18574-3-git-send-email-ard.biesheuvel@linaro.org>
Ard Biesheuvel <ard.biesheuvel@linaro.org> writes:
> diff --git a/arch/powerpc/relocs_check.sh b/arch/powerpc/relocs_check.sh
> index ec2d5c835170..2f510fbc87da 100755
> --- a/arch/powerpc/relocs_check.sh
> +++ b/arch/powerpc/relocs_check.sh
> @@ -43,7 +43,8 @@ R_PPC_ADDR16_HA
> R_PPC_RELATIVE
> R_PPC_NONE' |
> grep -E -v '\<R_PPC64_ADDR64[[:space:]]+mach_' |
> - grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_'
> + grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_' |
> + grep -E -v '\<R_PPC64_ADDR32[[:space:]]+\*ABS\*'
I'm still getting:
WARNING: 24 bad relocations
c000000000d307c4 R_PPC64_ADDR32 __crc___arch_hweight16
c000000000d307c8 R_PPC64_ADDR32 __crc___arch_hweight32
c000000000d307cc R_PPC64_ADDR32 __crc___arch_hweight64
c000000000d307d0 R_PPC64_ADDR32 __crc___arch_hweight8
c000000000d30848 R_PPC64_ADDR32 __crc___bswapdi2
c000000000d30854 R_PPC64_ADDR32 __crc___clear_user
c000000000d30868 R_PPC64_ADDR32 __crc___copy_tofrom_user
c000000000d30d4c R_PPC64_ADDR32 __crc__mcount
c000000000d31344 R_PPC64_ADDR32 __crc_copy_page
c000000000d3141c R_PPC64_ADDR32 __crc_current_stack_pointer
c000000000d31840 R_PPC64_ADDR32 __crc_empty_zero_page
c000000000d31a7c R_PPC64_ADDR32 __crc_flush_dcache_range
c000000000d31a84 R_PPC64_ADDR32 __crc_flush_icache_range
c000000000d32608 R_PPC64_ADDR32 __crc_load_fp_state
c000000000d32614 R_PPC64_ADDR32 __crc_load_vr_state
c000000000d32828 R_PPC64_ADDR32 __crc_memchr
c000000000d32830 R_PPC64_ADDR32 __crc_memcmp
c000000000d32834 R_PPC64_ADDR32 __crc_memcpy
c000000000d32840 R_PPC64_ADDR32 __crc_memmove
c000000000d32888 R_PPC64_ADDR32 __crc_memset
c000000000d33c9c R_PPC64_ADDR32 __crc_store_fp_state
c000000000d33ca0 R_PPC64_ADDR32 __crc_store_vr_state
c000000000d33cf0 R_PPC64_ADDR32 __crc_strncmp
c000000000d33cf4 R_PPC64_ADDR32 __crc_strncpy
If I just add those to the whitelist it builds, but then things aren't
happy@boot:
[ 7.607687] kvm: disagrees about version of symbol module_layout
[ 7.846799] virtio: disagrees about version of symbol module_layout
[ 22.012615] crc32c_vpmsum: disagrees about version of symbol module_layout
[ 22.012959] libcrc32c: disagrees about version of symbol module_layout
cheers
^ permalink raw reply
* [RFC PATCH 11/11] ARM: Allow ARCH_MULTIPLATFORM to be selected for NOMMU
From: Vladimir Murzin @ 2016-11-25 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161124184532.GI14217@n2100.armlinux.org.uk>
On 24/11/16 18:45, Russell King - ARM Linux wrote:
> It's this reason that I don't like removing the "depends on MMU" from
> multiplatform - it gives the incorrect impression that we _can_ support
> a wide range of systems, but what it will lead to is a kernel that will
> work on some platforms but not others. The result will be more "bug"
> reports because the kernel fails to boot...
Do you think extra guarding with CONFIG_EXPERIMENTAL would be appropriate to
reduce number of such reports?
Cheers
Vladimir
^ permalink raw reply
* [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay
From: Sebastian Frias @ 2016-11-25 11:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e6ca0941-e2e3-dd93-d4d3-8fbd76b60e17@gmail.com>
On 24/11/16 19:55, Florian Fainelli wrote:
> Le 24/11/2016 ? 09:05, Martin Blumenstingl a ?crit :
>> On Thu, Nov 24, 2016 at 4:56 PM, Jerome Brunet <jbrunet@baylibre.com> wrote:
>>> On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
>>>> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
>>>> cycle TX clock delay. This seems to work fine for many boards (for
>>>> example Odroid-C2 or Amlogic's reference boards) but there are some
>>>> others where TX traffic is simply broken.
>>>> There are probably multiple reasons why it's working on some boards
>>>> while it's broken on others:
>>>> - some of Amlogic's reference boards are using a Micrel PHY
>>>> - hardware circuit design
>>>> - maybe more...
>>>>
>>>> This raises a question though:
>>>> Which device is supposed to enable the TX delay when both MAC and PHY
>>>> support it? And should we implement it for each PHY / MAC separately
>>>> or should we think about a more generic solution (currently it's not
>>>> possible to disable the TX delay generated by the RTL8211F PHY via
>>>> devicetree when using phy-mode "rgmii")?
>>>
>>> Actually you can skip the part which activate the Tx-delay on the phy
>>> by setting "phy-mode = "rgmii-id" instead of "rgmii"
>>>
>>> phy->interface will no longer be PHY_INTERFACE_MODE_RGMII
>>> but PHY_INTERFACE_MODE_RGMII_ID.
>> unfortunately this is not true for RTL8211F (I did my previous tests
>> with the same expectation in mind)!
>> the code seems to suggest that TX-delay is disabled whenever mode !=
>> PHY_INTERFACE_MODE_RGMII.
>> BUT: on my device RTL8211F_TX_DELAY is set even before
>> "phy_write(phydev, 0x11, reg);"!
If you look at the Atheros 803x PHY and its driver
'drivers/net/phy/at803x.c':
- by default (as HW reset preset) the PHY has RX delay enabled, TX
delay disabled
- the driver only enables RX, or TX, or both, according to "rgmii-rxid",
"rgmii-txid", or "rgmii-id" respectively, but does not alter HW reset
presets. In other words:
a "rgmii-rxid" results in RX enabled (expected)
b "rgmii-txid" results in RX *and* TX enabled (unexpected?)
c "rgmii-id" results in RX *and* TX enabled (expected)
d "rgmii" results in RX enabled (unexpected?)
This is a bit surprising and I think that some boards and PHY<->MAC
combinations are working a little bit by chance, unless I'm missing
something.
>
> (Adding Sebastian (and Mans, and Andrew) since he raised the same
> question a while ago. I think I now understand a bit better what
> Sebastian was after a couple of weeks ago)
>
Thanks for CCing us, it is indeed a very similar issue.
>>
>> Based on what I found it seems that rgmii-id, rgmii-txid and
>> rgmii-rxid are supposed to be handled by the PHY.
>
> Correct, the meaning of PHY_INTERFACE_MODE should be from the
> perspective of the PHY device:
>
> - PHY_INTERFACE_MODE_RGMII_TXID means that the PHY is responsible for
> adding a delay when the MAC transmits (TX MAC -> PHY (delay) -> wire)
> - PHY_INTERFACE_MODE_RGMII_RXID means that the PHY is responsible for
> adding a delay when the MAC receives (RX MAC <- (delay) PHY) <- wire)
>
Thanks for the explanation.
Actually I had thought that the delay was to account for board routing
(wires) between the MAC and the PHY.
>From your explanation it appears that the delay is to account for board
routing (wires) between the PHY and the RJ45 socket.
>> That would mean that we have two problems here:
>> 1) drivers/net/phy/realtek.c:rtl8211f_config_init should check for
>> PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID and
>> enable the TX-delay in that case - otherwise explicitly disable it
>
> Agreed.
>
>> 2) dwmac-meson8b.c should only use the configured TX-delay for
>> PHY_INTERFACE_MODE_RGMII
>> @Florian: could you please share your thoughts on this (who handles
>> the TX delay in which case)?
>
> This also seems reasonable to do, provided that the PHY is also properly
> configured not to add delays in both directions, and therefore assumes
> that the MAC does it.
>
> We have a fairly large problem with how RGMII delays are done in PHYLIB
> and Ethernet MAC drivers (or just in general), where we can't really
> intersect properly what a PHY is supporting (in terms of internal
> delays), and what the MAC supports either. One possible approach could
> be to update PHY drivers a list of PHY_INTERFACE_MODE_* that they
> support (ideally, even with normalized nanosecond delay values),
Just to make sure I understood this, the DT would say something like:
phy-connection-type = "rgmii-txid";
txid-delay-ns = <3>;
For a 3ns TX delay, would that be good?
>and
> then intersect that with the requested phy_interface_t during
> phy_{attach,connect} time, and feed this back to the MAC with a special
> error code/callback, so we could gracefully try to choose another
> PHY_INTERFACE_MODE_* value that the MAC supports....
>
> A larger problem is that a number of drivers have been deployed, and
> Device Trees, possibly with the meaning of "phy-mode" and
> "phy-connection-type" being from the MAC perspective, and not the PHY
> perspective *sigh*, good luck auditing those.
>
> So from there, here is possibly what we could do
>
> - submit a series of patches that update the PHYLIB documentation (there
> are other things missing here) and make it clear from which entity (PHY
> or MAC) does the delay apply to, document the "intersection" problem here
I think documenting is necessary, thanks in advance!
However, I'm wondering if there's a way to make this work in all cases.
Indeed, if we consider for example that TX delay is required, we have 4
cases:
PHY | MAC | Who applies?
TXID supported | TXID supported | PHY
TXID supported | TXID not supported | PHY
TXID not supported | TXID supported | MAC
TXID not supported | TXID not supported | cannot be done
That is basically what my patch:
https://marc.info/?l=linux-netdev&m=147869658031783&w=2
attempted to achieve. That would allow more combinations of MAC<->PHY to
work, right?
Nevertheless, I think we also need to keep in mind that most of this
discussion assumes the case where both, MAC and PHY have equal capabilities.
Could it happen that the PHY supports only 2ns delay, and the MAC only
1ns delay?
Could it happen that the delay is bigger than what is supported by
either the PHY or MAC alone? maybe if combined it could work, for example
a 3ns delay required and the PHY supporting 2ns and the MAC 1ns, combined
it could work?
I don't know if these are cases worth supporting, nor if they are valid.
>
> - have you document the configured behavior for dwmac-meson8b that we
> just discussed here in v2 of this patch series
>
> Sorry for the long post, here is a virtual potato: 0
>
^ permalink raw reply
* [PATCH v3 0/3] modversions: Fix CRC mangling under CONFIG_RELOCATABLE=y
From: Michael Ellerman @ 2016-11-25 11:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8XZbh2SoS=yR0fzumrAEpQfc4pYE2m4tS66QXsTqS6=w@mail.gmail.com>
Ard Biesheuvel <ard.biesheuvel@linaro.org> writes:
> On 15 November 2016 at 09:13, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>> On 10 November 2016 at 05:22, Michael Ellerman <mpe@ellerman.id.au> wrote:
>>> Ard Biesheuvel <ard.biesheuvel@linaro.org> writes:
>>>
>>>> On 27 October 2016 at 17:27, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>>>> This series is a followup to the single patch 'modversions: treat symbol
>>>>> CRCs as 32 bit quantities on 64 bit archs', of which two versions have
>>>>> been sent out so far [0][1]
>>>>>
>>>>> As pointed out by Michael, GNU ld behaves a bit differently between arm64
>>>>> and PowerPC64, and where the former gets rid of all runtime relocations
>>>>> related to CRCs, the latter is not as easily convinced.
>>>>>
>>>>> Patch #1 fixes the issue where CRCs are corrupted by the runtime relocation
>>>>> routines for 32-bit PowerPC, for which the original fix was effectively
>>>>> reverted by commit 0e0ed6406e61 ("powerpc/modules: Module CRC relocation fix
>>>>> causes perf issues")
>>>>>
>>>>> Patch #2 adds handling of R_PPC64_ADDR32 relocations against the NULL .dynsym
>>>>> symbol entry to the PPC64 runtime relocation routines, so it is prepared to
>>>>> deal with CRCs being emitted as 32-bit quantities.
>>>>>
>>>>> Patch #3 is the original patch from the v1 and v2 submissions.
>>>>>
>>>>> Changes since v2:
>>>>> - added #1 and #2
>>>>> - updated #3 to deal with CRC entries being emitted from assembler
>>>>> - added Rusty's ack (#3)
>>>>>
>>>>> Branch can be found here:
>>>>> https://git.kernel.org/cgit/linux/kernel/git/ardb/linux.git/log/?h=kcrctab-reloc
>>>>>
>>>>> [0] http://marc.info/?l=linux-kernel&m=147652300207369&w=2
>>>>> [1] http://marc.info/?l=linux-kernel&m=147695629614409&w=2
>>>>
>>>> Ping?
>>>
>>> Sorry, you didn't cc linuxppc-dev, so it's not in my patchwork list
>>> which tends to mean I miss it.
>>
>> Ah, my mistake. Apologies.
>>
>>> Will try and test and get back to you.
>
> Ping?
Sorry :/
I tried testing it last week or so but it was interacting badly with the
other modversion CRC problems we were having (fixed recently in my fixes
branch).
I'll rebase on top of those fixes and try again.
cheers
^ permalink raw reply
* [RFC v2: PATCH 1/2] dt-bindings: Document the hi3660 reset bindings
From: Philipp Zabel @ 2016-11-25 10:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e71cfe28-cd31-828f-8c7f-b4faeed5d27f@linaro.org>
Am Freitag, den 25.11.2016, 18:42 +0800 schrieb zhangfei:
>
> On 2016?11?25? 18:25, Philipp Zabel wrote:
> > Am Donnerstag, den 24.11.2016, 18:20 +0800 schrieb zhangfei:
> >> On 2016?11?24? 17:50, Philipp Zabel wrote:
> >>> Am Donnerstag, den 24.11.2016, 17:40 +0800 schrieb zhangfei:
> >>>> On 2016?11?24? 17:26, Philipp Zabel wrote:
> >>>>> Am Mittwoch, den 23.11.2016, 16:07 +0800 schrieb Zhangfei Gao:
> >>>>>> Add DT bindings documentation for hi3660 SoC reset controller.
> >>>>>>
> >>>>>> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> >>>>>> ---
> >>>>>> .../bindings/reset/hisilicon,hi3660-reset.txt | 51 ++++++++++++++++++++++
> >>>>>> 1 file changed, 51 insertions(+)
> >>>>>> create mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
> >>>>>>
> >>>>>> diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
> >>>>>> new file mode 100644
> >>>>>> index 0000000..250daf2
> >>>>>> --- /dev/null
> >>>>>> +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
> >>>>>> @@ -0,0 +1,51 @@
> >>>>>> +Hisilicon System Reset Controller
> >>>>>> +======================================
> >>>>>> +
> >>>>>> +Please also refer to reset.txt in this directory for common reset
> >>>>>> +controller binding usage.
> >>>>>> +
> >>>>>> +The reset controller registers are part of the system-ctl block on
> >>>>>> +hi3660 SoC.
> >>>>>> +
> >>>>>> +Required properties:
> >>>>>> +- compatible: should be
> >>>>>> + "hisilicon,hi3660-reset"
> >>>>>> +- #reset-cells: 1, see below
> >>>>>> +- hisi,rst-syscon: phandle of the reset's syscon.
> >>>>>> +- hisi,reset-bits: Contains the reset control register information
> >>>>>> + Should contain 2 cells for each reset exposed to
> >>>>>> + consumers, defined as:
> >>>>>> + Cell #1 : offset from the syscon register base
> >>>>>> + Cell #2 : bits position of the control register
> >>>>>> +
> >>>>>> +Example:
> >>>>>> + iomcu: iomcu at ffd7e000 {
> >>>>>> + compatible = "hisilicon,hi3660-iomcu", "syscon";
> >>>>>> + reg = <0x0 0xffd7e000 0x0 0x1000>;
> >>>>>> + };
> >>>>>> +
> >>>>>> + iomcu_rst: iomcu_rst_controller {
> >>>>> This should be
> >>>>> iomcu_rst: reset-controller {
> >>>>>
> >>>>>> + compatible = "hisilicon,hi3660-reset";
> >>>>>> + #reset-cells = <1>;
> >>>>>> + hisi,rst-syscon = <&iomcu>;
> >>>>>> + hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
> >>>>>> + 0x20 0x10 /* 1: i2c1 */
> >>>>>> + 0x20 0x20 /* 2: i2c2 */
> >>>>>> + 0x20 0x8000000>; /* 3: i2c6 */
> >>>>>> + };
> >>>>> The reset lines are controlled through iomcu bits, is there a reason not
> >>>>> to put the iomcu_rst node inside the iomcu node? That way the
> >>>>> hisi,rst-syscon property could be removed and the syscon could be
> >>>>> retrieved via the reset-controller parent node.
> >>>> iomcu is common registers, controls clock and reset, etc.
> >>>> So we use syscon, without mapping the registers everywhere.
> >>>> It is common case in hisilicon, same in hi6220.
> >>>>
> >>>> Also the #clock-cells and #reset-cells can not be put in the same node,
> >>>> if they are both using probe, since reset_probe will not be called.
> >>>>
> >>>> So we use hisi,rst-syscon as a general solution.
> >>> What I meant is this:
> >>>
> >>> iomcu: iomcu at ffd7e000 {
> >>> compatible = "hisilicon,hi3660-iomcu", "syscon", "simple-mfd";
> >>> reg = <0x0 0xffd7e000 0x0 0x1000>;
> >> #clock-cells = <1>;
> >>
> >> In my test, if there add #clock-cells = <1>, reset_probe will not be
> >> called any more.
> >> Since clk_probe is called first.
> >> No matter iomcu_rst is child node or not.
> > I don't understand this, does the clock driver bind to the iomcu node
> > using CLK_OF_DECLARE_DRIVER(..., "hisilicon,hi3660-iomcu", ...)?
>
> This method:CLK_OF_DECLARE_DRIVER is not prefered in clock,
> and we have to use probe instead, to make all driver build as modules as
> possible.
>
> For example hi3660.
> static struct platform_driver hi3660_clk_driver = {
> .probe = hi3660_clk_probe,
> .driver = {
> .name = "hi3660-clk",
> .of_match_table = hi3660_clk_match_table,
> },
> };
hi3660_clk_match_table contains the "hisilicon,hi3660-iomcu" compatible?
If so, you could call
of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
from hi3660_clk_probe instead of using "simple-mfd" to probe the iomcu
node's children.
regards
Philipp
^ permalink raw reply
* [PATCH 01/10] power: supply: axp20x_usb_power: use of_device_id data field instead of device_is_compatible
From: kbuild test robot @ 2016-11-25 10:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161125090921.23138-2-quentin.schulz@free-electrons.com>
Hi Quentin,
[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.9-rc6 next-20161124]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Quentin-Schulz/add-support-for-VBUS-max-current-and-min-voltage-limits-AXP20X-and-AXP22X-PMICs/20161125-172224
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: x86_64-randconfig-s5-11251757 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
drivers/power/supply/axp20x_usb_power.c: In function 'axp20x_usb_power_probe':
>> drivers/power/supply/axp20x_usb_power.c:233:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
power->axp20x_id = (int)of_id->data;
^
vim +233 drivers/power/supply/axp20x_usb_power.c
217 if (!of_device_is_available(pdev->dev.of_node))
218 return -ENODEV;
219
220 of_id = of_match_device(axp20x_usb_power_match, &pdev->dev);
221 if (!of_id)
222 return -ENODEV;
223
224 if (!axp20x) {
225 dev_err(&pdev->dev, "Parent drvdata not set\n");
226 return -EINVAL;
227 }
228
229 power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL);
230 if (!power)
231 return -ENOMEM;
232
> 233 power->axp20x_id = (int)of_id->data;
234
235 power->np = pdev->dev.of_node;
236 power->regmap = axp20x->regmap;
237
238 if (power->axp20x_id == AXP202_ID) {
239 /* Enable vbus valid checking */
240 ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
241 AXP20X_VBUS_MON_VBUS_VALID,
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 23302 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161125/f7be7673/attachment-0001.gz>
^ permalink raw reply
* [RFC PATCH 04/11] PCI: tegra: limit to MMU build only
From: Vladimir Murzin @ 2016-11-25 10:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161122112619.GA22862@ulmo.ba.sec>
On 22/11/16 11:26, Thierry Reding wrote:
> On Tue, Nov 22, 2016 at 10:54:01AM +0100, Arnd Bergmann wrote:
>> On Tuesday, November 22, 2016 9:40:39 AM CET Vladimir Murzin wrote:
>>> On 22/11/16 09:31, Arnd Bergmann wrote:
>>>> On Tuesday, November 22, 2016 9:26:01 AM CET Vladimir Murzin wrote:
>>>>> This driver uses functionality which available for MMU build only,
>>>>> thus add dependency on MMU.
>>>>>
>>>>> Cc: Thierry Reding <thierry.reding@gmail.com>
>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>>
>>>>
>>>> Can you be more specific about what requires the MMU here?
>>>>
>>>> Is it the I/O space remapping or something else?
>>>
>>> Yes it comes from I/O space remapping.
>>>
>>> The fill error log:
>>>
>>> CC drivers/pci/host/pci-tegra.o
>>> In file included from ./arch/arm/include/asm/page.h:22:0,
>>> from ./arch/arm/include/asm/thread_info.h:17,
>>> from ./include/linux/thread_info.h:58,
>>> from ./include/asm-generic/current.h:4,
>>> from ./arch/arm/include/generated/asm/current.h:1,
>>> from ./include/linux/mutex.h:13,
>>> from ./include/linux/notifier.h:13,
>>> from ./include/linux/clk.h:17,
>>> from drivers/pci/host/pci-tegra.c:29:
>>> drivers/pci/host/pci-tegra.c: In function 'tegra_pcie_bus_alloc':
>>> drivers/pci/host/pci-tegra.c:388:27: error: 'L_PTE_PRESENT' undeclared (first use in this function)
>>> pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
>>
>>
>> That is not the I/O space, that is the config space.
>>
>> Not sure what a better alternative would be, but the manual selection
>> of page flags makes the driver non-portable and dependent on architecture
>> specifics that it really shouldn't have to worry about.
>>
>> In common PCI code, we use pgprot_device(PAGE_KERNEL)) at some point,
>> and that sounds like the right thing to do, but ARM doesn't provide
>> an override for it and the fallback is pgprot_noncached(), which is
>> probably wrong here.
>
> Actually I think pgprot_noncached() is correct. Very early on we used to
> map this using ioremap() and I remember that working. I also just tested
> the pci-tegra driver with pgprot_device(PAGE_KERNEL) instead of the ARM-
> specific flags and it seems to work well.
>
I did try that, but tegra_pcie_bus_alloc() calls get_vm_area() so
drivers/built-in.o: In function `tegra_pcie_add_bus':
:(.text+0x7763c): undefined reference to `get_vm_area'
make: *** [vmlinux] Error 1
Cheers
Vladimir
> Thierry
>
^ permalink raw reply
* [RFC v2: PATCH 1/2] dt-bindings: Document the hi3660 reset bindings
From: zhangfei @ 2016-11-25 10:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480069523.4058.17.camel@pengutronix.de>
On 2016?11?25? 18:25, Philipp Zabel wrote:
> Am Donnerstag, den 24.11.2016, 18:20 +0800 schrieb zhangfei:
>> On 2016?11?24? 17:50, Philipp Zabel wrote:
>>> Am Donnerstag, den 24.11.2016, 17:40 +0800 schrieb zhangfei:
>>>> On 2016?11?24? 17:26, Philipp Zabel wrote:
>>>>> Am Mittwoch, den 23.11.2016, 16:07 +0800 schrieb Zhangfei Gao:
>>>>>> Add DT bindings documentation for hi3660 SoC reset controller.
>>>>>>
>>>>>> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
>>>>>> ---
>>>>>> .../bindings/reset/hisilicon,hi3660-reset.txt | 51 ++++++++++++++++++++++
>>>>>> 1 file changed, 51 insertions(+)
>>>>>> create mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
>>>>>> new file mode 100644
>>>>>> index 0000000..250daf2
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
>>>>>> @@ -0,0 +1,51 @@
>>>>>> +Hisilicon System Reset Controller
>>>>>> +======================================
>>>>>> +
>>>>>> +Please also refer to reset.txt in this directory for common reset
>>>>>> +controller binding usage.
>>>>>> +
>>>>>> +The reset controller registers are part of the system-ctl block on
>>>>>> +hi3660 SoC.
>>>>>> +
>>>>>> +Required properties:
>>>>>> +- compatible: should be
>>>>>> + "hisilicon,hi3660-reset"
>>>>>> +- #reset-cells: 1, see below
>>>>>> +- hisi,rst-syscon: phandle of the reset's syscon.
>>>>>> +- hisi,reset-bits: Contains the reset control register information
>>>>>> + Should contain 2 cells for each reset exposed to
>>>>>> + consumers, defined as:
>>>>>> + Cell #1 : offset from the syscon register base
>>>>>> + Cell #2 : bits position of the control register
>>>>>> +
>>>>>> +Example:
>>>>>> + iomcu: iomcu at ffd7e000 {
>>>>>> + compatible = "hisilicon,hi3660-iomcu", "syscon";
>>>>>> + reg = <0x0 0xffd7e000 0x0 0x1000>;
>>>>>> + };
>>>>>> +
>>>>>> + iomcu_rst: iomcu_rst_controller {
>>>>> This should be
>>>>> iomcu_rst: reset-controller {
>>>>>
>>>>>> + compatible = "hisilicon,hi3660-reset";
>>>>>> + #reset-cells = <1>;
>>>>>> + hisi,rst-syscon = <&iomcu>;
>>>>>> + hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
>>>>>> + 0x20 0x10 /* 1: i2c1 */
>>>>>> + 0x20 0x20 /* 2: i2c2 */
>>>>>> + 0x20 0x8000000>; /* 3: i2c6 */
>>>>>> + };
>>>>> The reset lines are controlled through iomcu bits, is there a reason not
>>>>> to put the iomcu_rst node inside the iomcu node? That way the
>>>>> hisi,rst-syscon property could be removed and the syscon could be
>>>>> retrieved via the reset-controller parent node.
>>>> iomcu is common registers, controls clock and reset, etc.
>>>> So we use syscon, without mapping the registers everywhere.
>>>> It is common case in hisilicon, same in hi6220.
>>>>
>>>> Also the #clock-cells and #reset-cells can not be put in the same node,
>>>> if they are both using probe, since reset_probe will not be called.
>>>>
>>>> So we use hisi,rst-syscon as a general solution.
>>> What I meant is this:
>>>
>>> iomcu: iomcu at ffd7e000 {
>>> compatible = "hisilicon,hi3660-iomcu", "syscon", "simple-mfd";
>>> reg = <0x0 0xffd7e000 0x0 0x1000>;
>> #clock-cells = <1>;
>>
>> In my test, if there add #clock-cells = <1>, reset_probe will not be
>> called any more.
>> Since clk_probe is called first.
>> No matter iomcu_rst is child node or not.
> I don't understand this, does the clock driver bind to the iomcu node
> using CLK_OF_DECLARE_DRIVER(..., "hisilicon,hi3660-iomcu", ...)?
This method:CLK_OF_DECLARE_DRIVER is not prefered in clock,
and we have to use probe instead, to make all driver build as modules as
possible.
For example hi3660.
static struct platform_driver hi3660_clk_driver = {
.probe = hi3660_clk_probe,
.driver = {
.name = "hi3660-clk",
.of_match_table = hi3660_clk_match_table,
},
};
static int __init hi3660_clk_init(void)
{
return platform_driver_register(&hi3660_clk_driver);
}
core_initcall(hi3660_clk_init);
And many examples in drivers/clock, just
#grep -rn probe drivers/clk/
drivers/clk/clk-axm5516.c:587: .probe = axmclk_probe,
If the parent node happen to be clock, and set
#clock-cells = <1>;
Then clock_probe/hi3660_clk_probe will be called first.
But reset_probe will not be called any more.
Thanks
>
> My comment was based only on this reset binding documentation and the
> example DT snippet. Could you point me to the clock driver probe code
> and show me a more complete part of the hi3660 device tree?
>
> regards
> Philipp
>
^ permalink raw reply
* [PATCH] mtd: nand: mxc: Fix mxc_v1 ooblayout
From: Marek Vasut @ 2016-11-25 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161125112725.0ee9d49d@bbrezillon>
On 11/25/2016 11:27 AM, Boris Brezillon wrote:
> On Fri, 25 Nov 2016 10:58:26 +0100
> Marek Vasut <marek.vasut@gmail.com> wrote:
>
>> On 11/25/2016 10:13 AM, Boris Brezillon wrote:
>>> Commit a894cf6c5a82 ("mtd: nand: mxc: switch to mtd_ooblayout_ops")
>>> introduced a bug in the OOB layout description. Even if the driver claims
>>> that 3 ECC bytes are reserved to protect 512 bytes of data, it's actually
>>> 5 ECC bytes to protect 512+6 bytes of data (some OOB bytes are also
>>> protected using extra ECC bytes).
>>>
>>> Fix the mxc_v1_ooblayout_{free,ecc}() functions to reflect this behavior.
>>>
>>> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
>>> Fixes: a894cf6c5a82 ("mtd: nand: mxc: switch to mtd_ooblayout_ops")
>>> Cc: <stable@vger.kernel.org>
>>> ---
>>> drivers/mtd/nand/mxc_nand.c | 5 ++---
>>> 1 file changed, 2 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
>>> index 61ca020c5272..c19ec4f0983e 100644
>>> --- a/drivers/mtd/nand/mxc_nand.c
>>> +++ b/drivers/mtd/nand/mxc_nand.c
>>> @@ -886,7 +886,7 @@ static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
>>> return -ERANGE;
>>>
>>> oobregion->offset = (section * 16) + 6;
>>> - oobregion->length = nand_chip->ecc.bytes;
>>> + oobregion->length = 5;
>>
>> Use a macro instead of hard-coding a value please :)
>
> Ideally, we should change ->eccbytes value in the
> imx27_nand_devtype_data and imx21_nand_devtype_data definitions, but I
> fear it could break other things.
I was wondering about that too :) Break what things ?
> I'll define a macro.
Thanks!
>>
>>> return 0;
>>> }
>>> @@ -908,8 +908,7 @@ static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section,
>>> oobregion->length = 4;
>>> }
>>> } else {
>>> - oobregion->offset = ((section - 1) * 16) +
>>> - nand_chip->ecc.bytes + 6;
>>> + oobregion->offset = ((section - 1) * 16) + 5 + 6;
>>
>> DTTO here, the math here is cryptic enough.
>>
>>> if (section < nand_chip->ecc.steps)
>>> oobregion->length = (section * 16) + 6 -
>>> oobregion->offset;
>>>
>>
>>
>
--
Best regards,
Marek Vasut
^ permalink raw reply
* [PATCH v10 13/13] drm/mediatek: add support for Mediatek SoC MT2701
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
This patch add support for the Mediatek MT2701 DISP subsystem.
There is only one OVL engine in MT2701.
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 8 ++++++++
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 ++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 17 +++++++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 7 +++++++
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 29 +++++++++++++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_dsi.c | 1 +
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 6 ++++++
7 files changed, 74 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 678595c..0adb0e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -35,6 +35,7 @@
#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
+#define DISP_REG_OVL_ADDR_MT2701 0x0040
#define DISP_REG_OVL_ADDR_MT8173 0x0f40
#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
@@ -302,12 +303,19 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
return 0;
}
+static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
+ .addr = DISP_REG_OVL_ADDR_MT2701,
+ .fmt_rgb565_is_0 = false,
+};
+
static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
.addr = DISP_REG_OVL_ADDR_MT8173,
.fmt_rgb565_is_0 = true,
};
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
+ { .compatible = "mediatek,mt2701-disp-ovl",
+ .data = &mt2701_ovl_driver_data},
{ .compatible = "mediatek,mt8173-disp-ovl",
.data = &mt8173_ovl_driver_data},
{},
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index e5e5318..b68a513 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -236,11 +236,17 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
return 0;
}
+static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
+ .fifo_size = SZ_4K,
+};
+
static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
.fifo_size = SZ_8K,
};
static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
+ { .compatible = "mediatek,mt2701-disp-rdma",
+ .data = &mt2701_rdma_driver_data},
{ .compatible = "mediatek,mt8173-disp-rdma",
.data = &mt8173_rdma_driver_data},
{},
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index a9b209c..8130f3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -60,6 +60,13 @@
#define MT8173_MUTEX_MOD_DISP_PWM1 BIT(24)
#define MT8173_MUTEX_MOD_DISP_OD BIT(25)
+#define MT2701_MUTEX_MOD_DISP_OVL BIT(3)
+#define MT2701_MUTEX_MOD_DISP_WDMA BIT(6)
+#define MT2701_MUTEX_MOD_DISP_COLOR BIT(7)
+#define MT2701_MUTEX_MOD_DISP_BLS BIT(9)
+#define MT2701_MUTEX_MOD_DISP_RDMA0 BIT(10)
+#define MT2701_MUTEX_MOD_DISP_RDMA1 BIT(12)
+
#define MUTEX_SOF_SINGLE_MODE 0
#define MUTEX_SOF_DSI0 1
#define MUTEX_SOF_DSI1 2
@@ -92,6 +99,15 @@ struct mtk_ddp {
const unsigned int *mutex_mod;
};
+static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+ [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
+ [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
+ [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
+ [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
+ [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
+ [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
+};
+
static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
@@ -390,6 +406,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
}
static const struct of_device_id ddp_driver_dt_match[] = {
+ { .compatible = "mediatek,mt2701-disp-mutex", .data = mt2701_mutex_mod},
{ .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
{},
};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 7fb32d8..b10b3f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -39,6 +39,7 @@
#define DISP_REG_UFO_START 0x0000
#define DISP_COLOR_CFG_MAIN 0x0400
+#define DISP_COLOR_START_MT2701 0x0f00
#define DISP_COLOR_START_MT8173 0x0c00
#define DISP_COLOR_START(comp) ((comp)->data->color_offset)
#define DISP_COLOR_WIDTH(comp) (DISP_COLOR_START(comp) + 0x50)
@@ -267,11 +268,17 @@ struct mtk_ddp_comp_match {
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
};
+static const struct mtk_ddp_comp_driver_data mt2701_color_driver_data = {
+ .color_offset = DISP_COLOR_START_MT2701,
+};
+
static const struct mtk_ddp_comp_driver_data mt8173_color_driver_data = {
.color_offset = DISP_COLOR_START_MT8173,
};
static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
+ { .compatible = "mediatek,mt2701-disp-color",
+ .data = &mt2701_color_driver_data},
{ .compatible = "mediatek,mt8173-disp-color",
.data = &mt8173_color_driver_data},
{},
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 5f9b5e8..f5cb6f0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -126,6 +126,19 @@ static int mtk_atomic_commit(struct drm_device *drm,
.atomic_commit = mtk_atomic_commit,
};
+static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
+ DDP_COMPONENT_OVL0,
+ DDP_COMPONENT_RDMA0,
+ DDP_COMPONENT_COLOR0,
+ DDP_COMPONENT_BLS,
+ DDP_COMPONENT_DSI0,
+};
+
+static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = {
+ DDP_COMPONENT_RDMA1,
+ DDP_COMPONENT_DPI0,
+};
+
static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
DDP_COMPONENT_OVL0,
DDP_COMPONENT_COLOR0,
@@ -145,6 +158,14 @@ static int mtk_atomic_commit(struct drm_device *drm,
DDP_COMPONENT_DPI0,
};
+static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
+ .main_path = mt2701_mtk_ddp_main,
+ .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
+ .ext_path = mt2701_mtk_ddp_ext,
+ .ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
+ .shadow_register = true,
+};
+
static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
.main_path = mt8173_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
@@ -340,16 +361,22 @@ static void mtk_drm_unbind(struct device *dev)
};
static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
+ { .compatible = "mediatek,mt2701-disp-ovl", .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8173-disp-ovl", .data = (void *)MTK_DISP_OVL },
+ { .compatible = "mediatek,mt2701-disp-rdma", .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-rdma", .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-wdma", .data = (void *)MTK_DISP_WDMA },
+ { .compatible = "mediatek,mt2701-disp-color", .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-color", .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-aal", .data = (void *)MTK_DISP_AAL},
{ .compatible = "mediatek,mt8173-disp-gamma", .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8173-disp-ufoe", .data = (void *)MTK_DISP_UFOE },
+ { .compatible = "mediatek,mt2701-dsi", .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dsi", .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dpi", .data = (void *)MTK_DPI },
+ { .compatible = "mediatek,mt2701-disp-mutex", .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8173-disp-mutex", .data = (void *)MTK_DISP_MUTEX },
+ { .compatible = "mediatek,mt2701-disp-pwm", .data = (void *)MTK_DISP_BLS },
{ .compatible = "mediatek,mt8173-disp-pwm", .data = (void *)MTK_DISP_PWM },
{ .compatible = "mediatek,mt8173-disp-od", .data = (void *)MTK_DISP_OD },
{ }
@@ -522,6 +549,8 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
mtk_drm_sys_resume);
static const struct of_device_id mtk_drm_of_ids[] = {
+ { .compatible = "mediatek,mt2701-mmsys",
+ .data = &mt2701_mmsys_driver_data},
{ .compatible = "mediatek,mt8173-mmsys",
.data = &mt8173_mmsys_driver_data},
{ }
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 0569f2e..f63cc91 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1203,6 +1203,7 @@ static int mtk_dsi_remove(struct platform_device *pdev)
}
static const struct of_device_id mtk_dsi_of_match[] = {
+ { .compatible = "mediatek,mt2701-dsi" },
{ .compatible = "mediatek,mt8173-dsi" },
{ },
};
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index 1ef00ac..00cc906 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -467,11 +467,17 @@ 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 },
{},
--
1.9.1
^ permalink raw reply related
* [PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
This patch update enable/disable flow of DSI module.
Original flow works on there is a bridge chip: DSI -> bridge -> panel.
In this case: DSI -> panel, the DSI sub driver flow should be updated.
We need to initialize DSI first so that we can send commands to panel.
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 101 +++++++++++++++++++++++++++++--------
1 file changed, 80 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ded4202..0569f2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
#define CLK_HS_POST (0xff << 8)
#define CLK_HS_EXIT (0xff << 16)
+#define DSI_VM_CMD_CON 0x130
+#define VM_CMD_EN BIT(0)
+#define TS_VFP_EN BIT(5)
+
#define DSI_CMDQ0 0x180
#define CONFIG (0xff << 0)
#define SHORT_PACKET 0
@@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
* mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
* we set mipi_ratio is 1.05.
*/
- dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+ dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
+ dsi->data_rate /= (dsi->lanes * 1000 * 10);
+ DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);
ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
if (ret < 0) {
@@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
u32 vid_mode = CMD_MODE;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
- vid_mode = SYNC_PULSE_MODE;
-
- if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
- !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
vid_mode = BURST_MODE;
+ else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+ vid_mode = SYNC_PULSE_MODE;
+ else
+ vid_mode = SYNC_EVENT_MODE;
}
writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
}
+static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
+{
+ mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
+ mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+}
+
static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
{
struct videomode *vm = &dsi->vm;
@@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
writel(1, dsi->regs + DSI_START);
}
+static void mtk_dsi_stop(struct mtk_dsi *dsi)
+{
+ writel(0, dsi->regs + DSI_START);
+}
+
+static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
+{
+ writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+}
+
static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
{
u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
+{
+ mtk_dsi_irq_data_clear(dsi, irq_flag);
+ mtk_dsi_set_cmd_mode(dsi);
+
+ if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
+ DRM_ERROR("failed to switch cmd mode\n");
+ return -ETIME;
+ } else {
+ return 0;
+ }
+}
+
static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
{
if (WARN_ON(dsi->refcount == 0))
@@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
if (--dsi->refcount != 0)
return;
- mtk_dsi_lane0_ulp_mode_enter(dsi);
- mtk_dsi_clk_ulp_mode_enter(dsi);
-
- mtk_dsi_disable(dsi);
-
clk_disable_unprepare(dsi->engine_clk);
clk_disable_unprepare(dsi->digital_clk);
@@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
if (dsi->enabled)
return;
- if (dsi->panel) {
- if (drm_panel_prepare(dsi->panel)) {
- DRM_ERROR("failed to setup the panel\n");
- return;
- }
- }
-
ret = mtk_dsi_poweron(dsi);
if (ret < 0) {
DRM_ERROR("failed to power on dsi\n");
@@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
}
mtk_dsi_rxtx_control(dsi);
+ mtk_dsi_ps_control_vact(dsi);
+ mtk_dsi_set_vm_cmd(dsi);
+ mtk_dsi_config_vdo_timing(dsi);
+ mtk_dsi_set_interrupt_enable(dsi);
mtk_dsi_clk_ulp_mode_leave(dsi);
mtk_dsi_lane0_ulp_mode_leave(dsi);
mtk_dsi_clk_hs_mode(dsi, 0);
- mtk_dsi_set_mode(dsi);
- mtk_dsi_ps_control_vact(dsi);
- mtk_dsi_config_vdo_timing(dsi);
- mtk_dsi_set_interrupt_enable(dsi);
+ if (dsi->panel) {
+ if (drm_panel_prepare(dsi->panel)) {
+ DRM_ERROR("failed to prepare the panel\n");
+
+ mtk_dsi_stop(dsi);
+ mtk_dsi_poweroff(dsi);
+ return;
+ }
+ }
mtk_dsi_set_mode(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
mtk_dsi_start(dsi);
+ if (dsi->panel) {
+ if (drm_panel_enable(dsi->panel)) {
+ DRM_ERROR("failed to enable the panel\n");
+
+ if (drm_panel_unprepare(dsi->panel))
+ DRM_ERROR("failed to unprepare the panel\n");
+
+ mtk_dsi_stop(dsi);
+ mtk_dsi_poweroff(dsi);
+ return;
+ }
+ }
+
dsi->enabled = true;
}
@@ -608,6 +654,19 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
}
}
+ mtk_dsi_stop(dsi);
+ if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+ if (dsi->panel) {
+ if (drm_panel_unprepare(dsi->panel))
+ DRM_ERROR("failed to unprepare the panel\n");
+ }
+ }
+
+ mtk_dsi_reset_engine(dsi);
+ mtk_dsi_lane0_ulp_mode_enter(dsi);
+ mtk_dsi_clk_ulp_mode_enter(dsi);
+ mtk_dsi_disable(dsi);
+
mtk_dsi_poweroff(dsi);
dsi->enabled = false;
--
1.9.1
^ permalink raw reply related
* [PATCH v10 11/13] drm/mediatek: add dsi rxtx control
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
add non-continuous clock mode and EOT packet control for dsi
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 01df829..ded4202 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -399,6 +399,9 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
break;
}
+ tmp_reg |= (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
+ tmp_reg |= (dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
+
writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
}
--
1.9.1
^ permalink raw reply related
* [PATCH v10 10/13] drm/mediatek: add dsi ulp mode control
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
modify dsi enter ultra low power mode method
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index d03a0f1..01df829 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -289,7 +289,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
- mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
+ mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, LC_ULPM_EN);
}
static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
@@ -302,7 +302,7 @@ static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
- mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
+ mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, LD0_ULPM_EN);
}
static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
--
1.9.1
^ permalink raw reply related
* [PATCH v10 09/13] drm/mediatek: add mipi_tx data rate check
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
modify data rate limitation (>lGbps/lane) for mipitx
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index fd84914..1ef00ac 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -177,7 +177,9 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
- if (mipi_tx->data_rate >= 500000000) {
+ if (mipi_tx->data_rate > 1250000000) {
+ return -EINVAL;
+ } else if (mipi_tx->data_rate >= 500000000) {
txdiv = 1;
txdiv0 = 0;
txdiv1 = 0;
--
1.9.1
^ permalink raw reply related
* [PATCH v10 08/13] drm/mediatek: add dsi transfer function
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
From: shaoming chen <shaoming.chen@mediatek.com>
add dsi read/write commands for transfer function
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 168 ++++++++++++++++++++++++++++++++++++-
1 file changed, 166 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index d236e2d..d03a0f1 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -24,6 +24,7 @@
#include <linux/of_graph.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <video/mipi_display.h>
#include <video/videomode.h>
#include "mtk_drm_ddp_comp.h"
@@ -80,8 +81,16 @@
#define DSI_HBP_WC 0x54
#define DSI_HFP_WC 0x58
+#define DSI_CMDQ_SIZE 0x60
+#define CMDQ_SIZE 0x3f
+
#define DSI_HSTX_CKL_WC 0x64
+#define DSI_RX_DATA0 0x74
+#define DSI_RX_DATA1 0x78
+#define DSI_RX_DATA2 0x7c
+#define DSI_RX_DATA3 0x80
+
#define DSI_RACK 0x84
#define RACK BIT(0)
@@ -117,8 +126,23 @@
#define CLK_HS_POST (0xff << 8)
#define CLK_HS_EXIT (0xff << 16)
+#define DSI_CMDQ0 0x180
+#define CONFIG (0xff << 0)
+#define SHORT_PACKET 0
+#define LONG_PACKET 2
+#define BTA BIT(2)
+#define DATA_ID (0xff << 8)
+#define DATA_0 (0xff << 16)
+#define DATA_1 (0xff << 24)
+
#define NS_TO_CYCLE(n, c) ((n) / (c) + (((n) % (c)) ? 1 : 0))
+#define MTK_DSI_HOST_IS_READ(type) \
+ ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
+ (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
+ (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
+ (type == MIPI_DSI_DCS_READ))
+
struct phy;
struct mtk_dsi {
@@ -465,12 +489,12 @@ static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 irq_bit)
dsi->irq_data |= irq_bit;
}
-static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
+static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
{
dsi->irq_data &= ~irq_bit;
}
-static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
+static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
unsigned int timeout)
{
s32 ret = 0;
@@ -807,9 +831,149 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
}
+static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
+{
+ u32 timeout_ms = 500000; /* total 1s ~ 2s timeout */
+
+ while (timeout_ms--) {
+ if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
+ break;
+
+ usleep_range(2, 4);
+ }
+
+ if (timeout_ms == 0) {
+ DRM_WARN("polling dsi wait not busy timeout!\n");
+
+ mtk_dsi_enable(dsi);
+ mtk_dsi_reset_engine(dsi);
+ }
+}
+
+static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
+{
+ switch (type) {
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+ return 1;
+ case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+ case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+ return 2;
+ case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
+ case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
+ return read_data[1] + read_data[2] * 16;
+ case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+ DRM_INFO("type is 0x02, try again\n");
+ break;
+ default:
+ DRM_INFO("type(0x%x) cannot be non-recognite\n", type);
+ break;
+ }
+
+ return 0;
+}
+
+static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
+{
+ const char *tx_buf = msg->tx_buf;
+ u8 config, cmdq_size, cmdq_off, type = msg->type;
+ u32 reg_val, cmdq_mask, i;
+
+ if (MTK_DSI_HOST_IS_READ(type))
+ config = BTA;
+ else
+ config = (msg->tx_len > 2) ? LONG_PACKET : SHORT_PACKET;
+
+ if (msg->tx_len > 2) {
+ cmdq_size = 1 + (msg->tx_len + 3) / 4;
+ cmdq_off = 4;
+ cmdq_mask = CONFIG | DATA_ID | DATA_0 | DATA_1;
+ reg_val = (msg->tx_len << 16) | (type << 8) | config;
+ } else {
+ cmdq_size = 1;
+ cmdq_off = 2;
+ cmdq_mask = CONFIG | DATA_ID;
+ reg_val = (type << 8) | config;
+ }
+
+ for (i = 0; i < msg->tx_len; i++)
+ writeb(tx_buf[i], dsi->regs + DSI_CMDQ0 + cmdq_off + i);
+
+ mtk_dsi_mask(dsi, DSI_CMDQ0, cmdq_mask, reg_val);
+ mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size);
+}
+
+static ssize_t mtk_dsi_host_send_cmd(struct mtk_dsi *dsi,
+ const struct mipi_dsi_msg *msg, u8 flag)
+{
+ mtk_dsi_wait_for_idle(dsi);
+ mtk_dsi_irq_data_clear(dsi, flag);
+ mtk_dsi_cmdq(dsi, msg);
+ mtk_dsi_start(dsi);
+
+ if (!mtk_dsi_wait_for_irq_done(dsi, flag, 2000))
+ return -ETIME;
+ else
+ return 0;
+}
+
+static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct mtk_dsi *dsi = host_to_dsi(host);
+ u32 recv_cnt, i;
+ u8 read_data[16];
+ void *src_addr;
+ u8 irq_flag = CMD_DONE_INT_FLAG;
+
+ if (readl(dsi->regs + DSI_MODE_CTRL) & MODE) {
+ DRM_ERROR("dsi engine is not command mode\n");
+ return -EINVAL;
+ }
+
+ if (MTK_DSI_HOST_IS_READ(msg->type))
+ irq_flag |= LPRX_RD_RDY_INT_FLAG;
+
+ if (mtk_dsi_host_send_cmd(dsi, msg, irq_flag) < 0)
+ return -ETIME;
+
+ if (!MTK_DSI_HOST_IS_READ(msg->type))
+ return 0;
+
+ if (!msg->rx_buf) {
+ DRM_ERROR("dsi receive buffer size may be NULL\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 16; i++)
+ *(read_data + i) = readb(dsi->regs + DSI_RX_DATA0 + i);
+
+ recv_cnt = mtk_dsi_recv_cnt(read_data[0], read_data);
+
+ if (recv_cnt > 2)
+ src_addr = &read_data[4];
+ else
+ src_addr = &read_data[1];
+
+ if (recv_cnt > 10)
+ recv_cnt = 10;
+
+ if (recv_cnt > msg->rx_len)
+ recv_cnt = msg->rx_len;
+
+ if (recv_cnt)
+ memcpy(msg->rx_buf, src_addr, recv_cnt);
+
+ DRM_INFO("dsi get %d byte data from the panel address(0x%x)\n",
+ recv_cnt, *((u8 *)(msg->tx_buf)));
+
+ return recv_cnt;
+}
+
static const struct mipi_dsi_host_ops mtk_dsi_ops = {
.attach = mtk_dsi_host_attach,
.detach = mtk_dsi_host_detach,
+ .transfer = mtk_dsi_host_transfer,
};
static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
--
1.9.1
^ permalink raw reply related
* [PATCH v10 07/13] drm/mediatek: add dsi interrupt control
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
From: shaoming chen <shaoming.chen@mediatek.com>
add dsi interrupt control
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 92 ++++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 4efeb38..d236e2d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -18,6 +18,7 @@
#include <drm/drm_panel.h>
#include <linux/clk.h>
#include <linux/component.h>
+#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_graph.h>
@@ -29,6 +30,16 @@
#define DSI_START 0x00
+#define DSI_INTEN 0x08
+
+#define DSI_INTSTA 0x0c
+#define LPRX_RD_RDY_INT_FLAG BIT(0)
+#define CMD_DONE_INT_FLAG BIT(1)
+#define TE_RDY_INT_FLAG BIT(2)
+#define VM_DONE_INT_FLAG BIT(3)
+#define EXT_TE_RDY_INT_FLAG BIT(4)
+#define DSI_BUSY BIT(31)
+
#define DSI_CON_CTRL 0x10
#define DSI_RESET BIT(0)
#define DSI_EN BIT(1)
@@ -71,6 +82,9 @@
#define DSI_HSTX_CKL_WC 0x64
+#define DSI_RACK 0x84
+#define RACK BIT(0)
+
#define DSI_PHY_LCCON 0x104
#define LC_HS_TX_EN BIT(0)
#define LC_ULPM_EN BIT(1)
@@ -131,6 +145,8 @@ struct mtk_dsi {
struct videomode vm;
int refcount;
bool enabled;
+ u32 irq_data;
+ wait_queue_head_t irq_wait_queue;
};
static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
@@ -437,6 +453,64 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
writel(1, dsi->regs + DSI_START);
}
+static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
+{
+ u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
+
+ writel(inten, dsi->regs + DSI_INTEN);
+}
+
+static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 irq_bit)
+{
+ dsi->irq_data |= irq_bit;
+}
+
+static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
+{
+ dsi->irq_data &= ~irq_bit;
+}
+
+static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
+ unsigned int timeout)
+{
+ s32 ret = 0;
+ unsigned long jiffies = msecs_to_jiffies(timeout);
+
+ ret = wait_event_interruptible_timeout(dsi->irq_wait_queue,
+ dsi->irq_data & irq_flag,
+ jiffies);
+ if (ret == 0) {
+ DRM_WARN("Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
+
+ mtk_dsi_enable(dsi);
+ mtk_dsi_reset_engine(dsi);
+ }
+
+ return ret;
+}
+
+static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
+{
+ struct mtk_dsi *dsi = dev_id;
+ u32 status, tmp;
+ u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
+
+ status = readl(dsi->regs + DSI_INTSTA) & flag;
+
+ if (status) {
+ do {
+ mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
+ tmp = readl(dsi->regs + DSI_INTSTA);
+ } while (tmp & DSI_BUSY);
+
+ mtk_dsi_mask(dsi, DSI_INTSTA, status, 0);
+ mtk_dsi_irq_data_set(dsi, status);
+ wake_up_interruptible(&dsi->irq_wait_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
{
if (WARN_ON(dsi->refcount == 0))
@@ -485,6 +559,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
mtk_dsi_ps_control_vact(dsi);
mtk_dsi_config_vdo_timing(dsi);
+ mtk_dsi_set_interrupt_enable(dsi);
mtk_dsi_set_mode(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
@@ -793,6 +868,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *remote_node, *endpoint;
struct resource *regs;
+ int irq_num;
int comp_id;
int ret;
@@ -869,6 +945,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
return ret;
}
+ irq_num = platform_get_irq(pdev, 0);
+ if (irq_num < 0) {
+ dev_err(&pdev->dev, "failed to request dsi irq resource\n");
+ return -EPROBE_DEFER;
+ }
+
+ irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
+ ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
+ IRQF_TRIGGER_LOW, dev_name(&pdev->dev), dsi);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
+ return -EPROBE_DEFER;
+ }
+
+ init_waitqueue_head(&dsi->irq_wait_queue);
+
platform_set_drvdata(pdev, dsi);
return component_add(&pdev->dev, &mtk_dsi_component_ops);
--
1.9.1
^ permalink raw reply related
* [PATCH v10 06/13] drm/mediatek: cleaning up and refine
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
cleaning up unused define and refine function name and variable
Signed-off-by: shaoming chen <shaoming.chen@mediatek.com>
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 77 ++++++++++++++++------------------
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 8 ++--
2 files changed, 41 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 28b2044..4efeb38 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -27,9 +27,6 @@
#include "mtk_drm_ddp_comp.h"
-#define DSI_VIDEO_FIFO_DEPTH (1920 / 4)
-#define DSI_HOST_FIFO_DEPTH 64
-
#define DSI_START 0x00
#define DSI_CON_CTRL 0x10
@@ -46,7 +43,7 @@
#define MIX_MODE BIT(17)
#define DSI_TXRX_CTRL 0x18
-#define VC_NUM (2 << 0)
+#define VC_NUM BIT(1)
#define LANE_NUM (0xf << 2)
#define DIS_EOT BIT(6)
#define NULL_EN BIT(7)
@@ -158,11 +155,11 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
writel((temp & ~mask) | (data & mask), dsi->regs + offset);
}
-static void dsi_phy_timconfig(struct mtk_dsi *dsi)
+static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
{
u32 timcon0, timcon1, timcon2, timcon3;
- unsigned int ui, cycle_time;
- unsigned int lpx;
+ u32 ui, cycle_time;
+ u32 lpx;
ui = 1000 / dsi->data_rate + 0x01;
cycle_time = 8000 / dsi->data_rate + 0x01;
@@ -192,7 +189,7 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
}
-static void mtk_dsi_reset(struct mtk_dsi *dsi)
+static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
@@ -235,8 +232,8 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
}
mtk_dsi_enable(dsi);
- mtk_dsi_reset(dsi);
- dsi_phy_timconfig(dsi);
+ mtk_dsi_reset_engine(dsi);
+ mtk_dsi_phy_timconfig(dsi);
return 0;
@@ -249,33 +246,33 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
return ret;
}
-static void dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
+static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
}
-static void dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
+static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, LC_WAKEUP_EN);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, 0);
}
-static void dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
+static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
}
-static void dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
+static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
{
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, LD0_WAKEUP_EN);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, 0);
}
-static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
+static bool mtk_dsi_clk_hs_state(struct mtk_dsi *dsi)
{
u32 tmp_reg1;
@@ -283,15 +280,15 @@ static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
return ((tmp_reg1 & LC_HS_TX_EN) == 1) ? true : false;
}
-static void dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
+static void mtk_dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
{
- if (enter && !dsi_clk_hs_state(dsi))
+ if (enter && !mtk_dsi_clk_hs_state(dsi))
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, LC_HS_TX_EN);
- else if (!enter && dsi_clk_hs_state(dsi))
+ else if (!enter && mtk_dsi_clk_hs_state(dsi))
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
}
-static void dsi_set_mode(struct mtk_dsi *dsi)
+static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
{
u32 vid_mode = CMD_MODE;
@@ -306,7 +303,7 @@ static void dsi_set_mode(struct mtk_dsi *dsi)
writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
}
-static void dsi_ps_control_vact(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
{
struct videomode *vm = &dsi->vm;
u32 dsi_buf_bpp, ps_wc;
@@ -340,7 +337,7 @@ static void dsi_ps_control_vact(struct mtk_dsi *dsi)
writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
}
-static void dsi_rxtx_control(struct mtk_dsi *dsi)
+static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
{
u32 tmp_reg;
@@ -365,9 +362,9 @@ static void dsi_rxtx_control(struct mtk_dsi *dsi)
writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
}
-static void dsi_ps_control(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
{
- unsigned int dsi_tmp_buf_bpp;
+ u32 dsi_tmp_buf_bpp;
u32 tmp_reg;
switch (dsi->format) {
@@ -397,12 +394,12 @@ static void dsi_ps_control(struct mtk_dsi *dsi)
writel(tmp_reg, dsi->regs + DSI_PSCTRL);
}
-static void dsi_config_vdo_timing(struct mtk_dsi *dsi)
+static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
{
- unsigned int horizontal_sync_active_byte;
- unsigned int horizontal_backporch_byte;
- unsigned int horizontal_frontporch_byte;
- unsigned int dsi_tmp_buf_bpp;
+ u32 horizontal_sync_active_byte;
+ u32 horizontal_backporch_byte;
+ u32 horizontal_frontporch_byte;
+ u32 dsi_tmp_buf_bpp;
struct videomode *vm = &dsi->vm;
@@ -431,7 +428,7 @@ static void dsi_config_vdo_timing(struct mtk_dsi *dsi)
writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
- dsi_ps_control(dsi);
+ mtk_dsi_ps_control(dsi);
}
static void mtk_dsi_start(struct mtk_dsi *dsi)
@@ -448,8 +445,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
if (--dsi->refcount != 0)
return;
- dsi_lane0_ulp_mode_enter(dsi);
- dsi_clk_ulp_mode_enter(dsi);
+ mtk_dsi_lane0_ulp_mode_enter(dsi);
+ mtk_dsi_clk_ulp_mode_enter(dsi);
mtk_dsi_disable(dsi);
@@ -479,18 +476,18 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
return;
}
- dsi_rxtx_control(dsi);
+ mtk_dsi_rxtx_control(dsi);
- dsi_clk_ulp_mode_leave(dsi);
- dsi_lane0_ulp_mode_leave(dsi);
- dsi_clk_hs_mode(dsi, 0);
- dsi_set_mode(dsi);
+ mtk_dsi_clk_ulp_mode_leave(dsi);
+ mtk_dsi_lane0_ulp_mode_leave(dsi);
+ mtk_dsi_clk_hs_mode(dsi, 0);
+ mtk_dsi_set_mode(dsi);
- dsi_ps_control_vact(dsi);
- dsi_config_vdo_timing(dsi);
+ mtk_dsi_ps_control_vact(dsi);
+ mtk_dsi_config_vdo_timing(dsi);
- dsi_set_mode(dsi);
- dsi_clk_hs_mode(dsi, 1);
+ mtk_dsi_set_mode(dsi);
+ mtk_dsi_clk_hs_mode(dsi, 1);
mtk_dsi_start(dsi);
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index c4a0165..fd84914 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -134,7 +134,7 @@ struct mtk_mipitx_data {
struct mtk_mipi_tx {
struct device *dev;
void __iomem *regs;
- unsigned int data_rate;
+ u32 data_rate;
const struct mtk_mipitx_data *driver_data;
struct clk_hw pll_hw;
struct clk *pll;
@@ -172,7 +172,7 @@ static void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 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);
- unsigned int txdiv, txdiv0, txdiv1;
+ u8 txdiv, txdiv0, txdiv1;
u64 pcw;
dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
@@ -326,7 +326,7 @@ static unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
static int mtk_mipi_tx_power_on_signal(struct phy *phy)
{
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
- unsigned int reg;
+ u32 reg;
for (reg = MIPITX_DSI_CLOCK_LANE;
reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
@@ -357,7 +357,7 @@ static int mtk_mipi_tx_power_on(struct phy *phy)
static void mtk_mipi_tx_power_off_signal(struct phy *phy)
{
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
- unsigned int reg;
+ u32 reg;
mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
RG_DSI_PAD_TIE_LOW_EN);
--
1.9.1
^ permalink raw reply related
* [PATCH v10 05/13] drm/mediatek: update display module connections
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
update connections for OVL, RDMA, BLS, DSI
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index b77d456..a9b209c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -32,6 +32,10 @@
#define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN 0x0c8
#define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100
+#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030
+#define DISP_REG_CONFIG_OUT_SEL 0x04c
+#define DISP_REG_CONFIG_DSI_SEL 0x050
+
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
@@ -71,6 +75,10 @@
#define DPI0_SEL_IN_RDMA1 0x1
#define COLOR1_SEL_IN_OVL1 0x1
+#define OVL_MOUT_EN_RDMA 0x1
+#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8
+#define DSI_SEL_IN_BLS 0x0
+
struct mtk_disp_mutex {
int id;
bool claimed;
@@ -111,6 +119,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
value = OVL0_MOUT_EN_COLOR0;
+ } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
+ *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
+ value = OVL_MOUT_EN_RDMA;
} else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
value = OD_MOUT_EN_RDMA0;
@@ -148,6 +159,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
value = COLOR1_SEL_IN_OVL1;
+ } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+ *addr = DISP_REG_CONFIG_DSI_SEL;
+ value = DSI_SEL_IN_BLS;
} else {
value = 0;
}
@@ -155,6 +169,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
return value;
}
+static void mtk_ddp_sout_sel(void __iomem *config_regs,
+ enum mtk_ddp_comp_id cur,
+ enum mtk_ddp_comp_id next)
+{
+ if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
+ writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
+ config_regs + DISP_REG_CONFIG_OUT_SEL);
+}
+
void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
enum mtk_ddp_comp_id cur,
enum mtk_ddp_comp_id next)
@@ -167,6 +190,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
writel_relaxed(reg, config_regs + addr);
}
+ mtk_ddp_sout_sel(config_regs, cur, next);
+
value = mtk_ddp_sel_in(cur, next, &addr);
if (value) {
reg = readl_relaxed(config_regs + addr) | value;
--
1.9.1
^ permalink raw reply related
* [PATCH v10 04/13] drm/mediatek: add BLS component
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
Add BLS component for PWM + GAMMA function
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 5 ++++-
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index d20f6cb..7fb32d8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -237,6 +237,7 @@ static void mtk_gamma_set(struct mtk_ddp_comp *comp,
[MTK_DISP_PWM] = "pwm",
[MTK_DISP_MUTEX] = "mutex",
[MTK_DISP_OD] = "od",
+ [MTK_DISP_BLS] = "bls",
};
struct mtk_ddp_comp_match {
@@ -247,6 +248,7 @@ struct mtk_ddp_comp_match {
static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL] = { MTK_DISP_AAL, 0, &ddp_aal },
+ [DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color },
[DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color },
[DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL },
@@ -305,7 +307,8 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
comp->id = comp_id;
comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
- if (comp_id == DDP_COMPONENT_DPI0 ||
+ if (comp_id == DDP_COMPONENT_BLS ||
+ comp_id == DDP_COMPONENT_DPI0 ||
comp_id == DDP_COMPONENT_DSI0 ||
comp_id == DDP_COMPONENT_PWM0) {
comp->regs = NULL;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index cfaa760..4bf68ae 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -36,11 +36,13 @@ enum mtk_ddp_comp_type {
MTK_DISP_PWM,
MTK_DISP_MUTEX,
MTK_DISP_OD,
+ MTK_DISP_BLS,
MTK_DDP_COMP_TYPE_MAX,
};
enum mtk_ddp_comp_id {
DDP_COMPONENT_AAL,
+ DDP_COMPONENT_BLS,
DDP_COMPONENT_COLOR0,
DDP_COMPONENT_COLOR1,
DDP_COMPONENT_DPI0,
--
1.9.1
^ permalink raw reply related
* [PATCH v10 03/13] drm/mediatek: add shadow register support
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
We need to acquire mutex before using the resources,
and need to release it after finished.
So we don't need to write registers in the blanking period.
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 76 ++++++++++++++++++++-------------
drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +++++++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp.h | 2 +
drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 +
4 files changed, 75 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 01a21dd..a4f2b3a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -329,6 +329,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
pm_runtime_put(drm->dev);
}
+static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
+{
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
+ struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+ unsigned int i;
+
+ /*
+ * TODO: instead of updating the registers here, we should prepare
+ * working registers in atomic_commit and let the hardware command
+ * queue update module registers on vblank.
+ */
+ if (state->pending_config) {
+ mtk_ddp_comp_config(ovl, state->pending_width,
+ state->pending_height,
+ state->pending_vrefresh, 0);
+
+ state->pending_config = false;
+ }
+
+ if (mtk_crtc->pending_planes) {
+ for (i = 0; i < OVL_LAYER_NR; i++) {
+ struct drm_plane *plane = &mtk_crtc->planes[i];
+ struct mtk_plane_state *plane_state;
+
+ plane_state = to_mtk_plane_state(plane->state);
+
+ if (plane_state->pending.config) {
+ mtk_ddp_comp_layer_config(ovl, i, plane_state);
+ plane_state->pending.config = false;
+ }
+ }
+ mtk_crtc->pending_planes = false;
+ }
+}
+
static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
@@ -405,6 +441,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0;
int i;
@@ -423,6 +460,13 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
}
if (pending_planes)
mtk_crtc->pending_planes = true;
+
+ if (priv->data->shadow_register) {
+ mtk_disp_mutex_acquire(mtk_crtc->mutex);
+ mtk_crtc_ddp_config(crtc);
+ mtk_disp_mutex_release(mtk_crtc->mutex);
+ }
+
if (crtc->state->color_mgmt_changed)
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
@@ -471,36 +515,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
- unsigned int i;
+ struct mtk_drm_private *priv = crtc->dev->dev_private;
- /*
- * TODO: instead of updating the registers here, we should prepare
- * working registers in atomic_commit and let the hardware command
- * queue update module registers on vblank.
- */
- if (state->pending_config) {
- mtk_ddp_comp_config(ovl, state->pending_width,
- state->pending_height,
- state->pending_vrefresh, 0);
-
- state->pending_config = false;
- }
-
- if (mtk_crtc->pending_planes) {
- for (i = 0; i < OVL_LAYER_NR; i++) {
- struct drm_plane *plane = &mtk_crtc->planes[i];
- struct mtk_plane_state *plane_state;
-
- plane_state = to_mtk_plane_state(plane->state);
-
- if (plane_state->pending.config) {
- mtk_ddp_comp_layer_config(ovl, i, plane_state);
- plane_state->pending.config = false;
- }
- }
- mtk_crtc->pending_planes = false;
- }
+ if (!priv->data->shadow_register)
+ mtk_crtc_ddp_config(crtc);
mtk_drm_finish_page_flip(mtk_crtc);
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index 8030769..b77d456 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -12,6 +12,7 @@
*/
#include <linux/clk.h>
+#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -32,10 +33,13 @@
#define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
+#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
#define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n))
#define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n))
+#define INT_MUTEX BIT(1)
+
#define MT8173_MUTEX_MOD_DISP_OVL0 BIT(11)
#define MT8173_MUTEX_MOD_DISP_OVL1 BIT(12)
#define MT8173_MUTEX_MOD_DISP_RDMA0 BIT(13)
@@ -300,6 +304,27 @@ void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex)
writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
}
+void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex)
+{
+ struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
+ mutex[mutex->id]);
+ u32 tmp;
+
+ writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
+ writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id));
+ if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id),
+ tmp, tmp & INT_MUTEX, 1, 10000))
+ pr_err("could not acquire mutex %d\n", mutex->id);
+}
+
+void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex)
+{
+ struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
+ mutex[mutex->id]);
+
+ writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id));
+}
+
static int mtk_ddp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
index 92c1175..f9a7991 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
@@ -37,5 +37,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
enum mtk_ddp_comp_id id);
void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex);
void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex);
+void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex);
+void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex);
#endif /* MTK_DRM_DDP_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index fa0b106..94f8b66 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -33,6 +33,7 @@ struct mtk_mmsys_driver_data {
unsigned int main_len;
const enum mtk_ddp_comp_id *ext_path;
unsigned int ext_len;
+ bool shadow_register;
};
struct mtk_drm_private {
--
1.9.1
^ permalink raw reply related
* [PATCH v10 02/13] drm/mediatek: add *driver_data for different hardware settings
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
There are some hardware settings changed, between MT8173 & MT2701:
DISP_OVL address offset changed, color format definition changed.
DISP_RDMA fifo size changed.
DISP_COLOR offset changed.
MIPI_TX pll setting changed.
And add prefix for mtk_ddp_main & mtk_ddp_ext & mutex_mod.
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 41 ++++++++++++-----
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 18 +++++++-
drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 71 +++++++++++++++--------------
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29 +++++++++---
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 5 ++
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 25 +++++++---
drivers/gpu/drm/mediatek/mtk_drm_drv.h | 8 ++++
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 24 +++++++++-
8 files changed, 160 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 17971e4..678595c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -35,18 +35,27 @@
#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
-#define DISP_REG_OVL_ADDR(n) (0x0f40 + 0x20 * (n))
+#define DISP_REG_OVL_ADDR_MT8173 0x0f40
+#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
#define OVL_RDMA_MEM_GMC 0x40402020
#define OVL_CON_BYTE_SWAP BIT(24)
-#define OVL_CON_CLRFMT_RGB565 (0 << 12)
-#define OVL_CON_CLRFMT_RGB888 (1 << 12)
+#define OVL_CON_CLRFMT_RGB (1 << 12)
#define OVL_CON_CLRFMT_RGBA8888 (2 << 12)
#define OVL_CON_CLRFMT_ARGB8888 (3 << 12)
+#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
+ 0 : OVL_CON_CLRFMT_RGB)
+#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
+ OVL_CON_CLRFMT_RGB : 0)
#define OVL_CON_AEN BIT(8)
#define OVL_CON_ALPHA 0xff
+struct mtk_disp_ovl_data {
+ unsigned int addr;
+ bool fmt_rgb565_is_0;
+};
+
/**
* struct mtk_disp_ovl - DISP_OVL driver structure
* @ddp_comp - structure containing type enum and hardware resources
@@ -55,6 +64,7 @@
struct mtk_disp_ovl {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ const struct mtk_disp_ovl_data *data;
};
static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
@@ -140,18 +150,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
}
-static unsigned int ovl_fmt_convert(unsigned int fmt)
+static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
{
switch (fmt) {
default:
case DRM_FORMAT_RGB565:
- return OVL_CON_CLRFMT_RGB565;
+ return OVL_CON_CLRFMT_RGB565(ovl);
case DRM_FORMAT_BGR565:
- return OVL_CON_CLRFMT_RGB565 | OVL_CON_BYTE_SWAP;
+ return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGB888:
- return OVL_CON_CLRFMT_RGB888;
+ return OVL_CON_CLRFMT_RGB888(ovl);
case DRM_FORMAT_BGR888:
- return OVL_CON_CLRFMT_RGB888 | OVL_CON_BYTE_SWAP;
+ return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGBX8888:
case DRM_FORMAT_RGBA8888:
return OVL_CON_CLRFMT_ARGB8888;
@@ -170,6 +180,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state)
{
+ struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
struct mtk_plane_pending_state *pending = &state->pending;
unsigned int addr = pending->addr;
unsigned int pitch = pending->pitch & 0xffff;
@@ -181,7 +192,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
if (!pending->enable)
mtk_ovl_layer_off(comp, idx);
- con = ovl_fmt_convert(fmt);
+ con = ovl_fmt_convert(ovl, fmt);
if (idx != 0)
con |= OVL_CON_AEN | OVL_CON_ALPHA;
@@ -189,7 +200,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
- writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(idx));
+ writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(ovl, idx));
if (pending->enable)
mtk_ovl_layer_on(comp, idx);
@@ -273,6 +284,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
return ret;
}
+ priv->data = of_device_get_match_data(dev);
+
platform_set_drvdata(pdev, priv);
ret = component_add(dev, &mtk_disp_ovl_component_ops);
@@ -289,8 +302,14 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
return 0;
}
+static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
+ .addr = DISP_REG_OVL_ADDR_MT8173,
+ .fmt_rgb565_is_0 = true,
+};
+
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
- { .compatible = "mediatek,mt8173-disp-ovl", },
+ { .compatible = "mediatek,mt8173-disp-ovl",
+ .data = &mt8173_ovl_driver_data},
{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 21eff6f..e5e5318 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -38,6 +38,11 @@
#define RDMA_FIFO_UNDERFLOW_EN BIT(31)
#define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
#define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16)
+#define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size)
+
+struct mtk_disp_rdma_data {
+ unsigned int fifo_size;
+};
/**
* struct mtk_disp_rdma - DISP_RDMA driver structure
@@ -47,6 +52,7 @@
struct mtk_disp_rdma {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ const struct mtk_disp_rdma_data *data;
};
static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
@@ -114,6 +120,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
{
unsigned int threshold;
unsigned int reg;
+ struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_1, 0xfffff, height);
@@ -126,7 +133,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
*/
threshold = width * height * vrefresh * 4 * 7 / 1000000;
reg = RDMA_FIFO_UNDERFLOW_EN |
- RDMA_FIFO_PSEUDO_SIZE(SZ_8K) |
+ RDMA_FIFO_PSEUDO_SIZE(RDMA_FIFO_SIZE(rdma)) |
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
}
@@ -211,6 +218,8 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
return ret;
}
+ priv->data = of_device_get_match_data(dev);
+
platform_set_drvdata(pdev, priv);
ret = component_add(dev, &mtk_disp_rdma_component_ops);
@@ -227,8 +236,13 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
return 0;
}
+static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
+ .fifo_size = SZ_8K,
+};
+
static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
- { .compatible = "mediatek,mt8173-disp-rdma", },
+ { .compatible = "mediatek,mt8173-disp-rdma",
+ .data = &mt8173_rdma_driver_data},
{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index 17ba935..8030769 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -36,21 +36,21 @@
#define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n))
#define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n))
-#define MUTEX_MOD_DISP_OVL0 BIT(11)
-#define MUTEX_MOD_DISP_OVL1 BIT(12)
-#define MUTEX_MOD_DISP_RDMA0 BIT(13)
-#define MUTEX_MOD_DISP_RDMA1 BIT(14)
-#define MUTEX_MOD_DISP_RDMA2 BIT(15)
-#define MUTEX_MOD_DISP_WDMA0 BIT(16)
-#define MUTEX_MOD_DISP_WDMA1 BIT(17)
-#define MUTEX_MOD_DISP_COLOR0 BIT(18)
-#define MUTEX_MOD_DISP_COLOR1 BIT(19)
-#define MUTEX_MOD_DISP_AAL BIT(20)
-#define MUTEX_MOD_DISP_GAMMA BIT(21)
-#define MUTEX_MOD_DISP_UFOE BIT(22)
-#define MUTEX_MOD_DISP_PWM0 BIT(23)
-#define MUTEX_MOD_DISP_PWM1 BIT(24)
-#define MUTEX_MOD_DISP_OD BIT(25)
+#define MT8173_MUTEX_MOD_DISP_OVL0 BIT(11)
+#define MT8173_MUTEX_MOD_DISP_OVL1 BIT(12)
+#define MT8173_MUTEX_MOD_DISP_RDMA0 BIT(13)
+#define MT8173_MUTEX_MOD_DISP_RDMA1 BIT(14)
+#define MT8173_MUTEX_MOD_DISP_RDMA2 BIT(15)
+#define MT8173_MUTEX_MOD_DISP_WDMA0 BIT(16)
+#define MT8173_MUTEX_MOD_DISP_WDMA1 BIT(17)
+#define MT8173_MUTEX_MOD_DISP_COLOR0 BIT(18)
+#define MT8173_MUTEX_MOD_DISP_COLOR1 BIT(19)
+#define MT8173_MUTEX_MOD_DISP_AAL BIT(20)
+#define MT8173_MUTEX_MOD_DISP_GAMMA BIT(21)
+#define MT8173_MUTEX_MOD_DISP_UFOE BIT(22)
+#define MT8173_MUTEX_MOD_DISP_PWM0 BIT(23)
+#define MT8173_MUTEX_MOD_DISP_PWM1 BIT(24)
+#define MT8173_MUTEX_MOD_DISP_OD BIT(25)
#define MUTEX_SOF_SINGLE_MODE 0
#define MUTEX_SOF_DSI0 1
@@ -77,24 +77,25 @@ struct mtk_ddp {
struct clk *clk;
void __iomem *regs;
struct mtk_disp_mutex mutex[10];
+ const unsigned int *mutex_mod;
};
-static const unsigned int mutex_mod[DDP_COMPONENT_ID_MAX] = {
- [DDP_COMPONENT_AAL] = MUTEX_MOD_DISP_AAL,
- [DDP_COMPONENT_COLOR0] = MUTEX_MOD_DISP_COLOR0,
- [DDP_COMPONENT_COLOR1] = MUTEX_MOD_DISP_COLOR1,
- [DDP_COMPONENT_GAMMA] = MUTEX_MOD_DISP_GAMMA,
- [DDP_COMPONENT_OD] = MUTEX_MOD_DISP_OD,
- [DDP_COMPONENT_OVL0] = MUTEX_MOD_DISP_OVL0,
- [DDP_COMPONENT_OVL1] = MUTEX_MOD_DISP_OVL1,
- [DDP_COMPONENT_PWM0] = MUTEX_MOD_DISP_PWM0,
- [DDP_COMPONENT_PWM1] = MUTEX_MOD_DISP_PWM1,
- [DDP_COMPONENT_RDMA0] = MUTEX_MOD_DISP_RDMA0,
- [DDP_COMPONENT_RDMA1] = MUTEX_MOD_DISP_RDMA1,
- [DDP_COMPONENT_RDMA2] = MUTEX_MOD_DISP_RDMA2,
- [DDP_COMPONENT_UFOE] = MUTEX_MOD_DISP_UFOE,
- [DDP_COMPONENT_WDMA0] = MUTEX_MOD_DISP_WDMA0,
- [DDP_COMPONENT_WDMA1] = MUTEX_MOD_DISP_WDMA1,
+static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+ [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
+ [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
+ [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
+ [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
+ [DDP_COMPONENT_OD] = MT8173_MUTEX_MOD_DISP_OD,
+ [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
+ [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
+ [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
+ [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
+ [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
+ [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
+ [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
+ [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
+ [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
+ [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
};
static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
@@ -247,7 +248,7 @@ void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
break;
default:
reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
- reg |= mutex_mod[id];
+ reg |= ddp->mutex_mod[id];
writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
return;
}
@@ -273,7 +274,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
break;
default:
reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
- reg &= ~mutex_mod[id];
+ reg &= ~(ddp->mutex_mod[id]);
writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
break;
}
@@ -326,6 +327,8 @@ static int mtk_ddp_probe(struct platform_device *pdev)
return PTR_ERR(ddp->regs);
}
+ ddp->mutex_mod = of_device_get_match_data(dev);
+
platform_set_drvdata(pdev, ddp);
return 0;
@@ -337,7 +340,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
}
static const struct of_device_id ddp_driver_dt_match[] = {
- { .compatible = "mediatek,mt8173-disp-mutex" },
+ { .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
{},
};
MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index df33b3c..d20f6cb 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -39,9 +39,10 @@
#define DISP_REG_UFO_START 0x0000
#define DISP_COLOR_CFG_MAIN 0x0400
-#define DISP_COLOR_START 0x0c00
-#define DISP_COLOR_WIDTH 0x0c50
-#define DISP_COLOR_HEIGHT 0x0c54
+#define DISP_COLOR_START_MT8173 0x0c00
+#define DISP_COLOR_START(comp) ((comp)->data->color_offset)
+#define DISP_COLOR_WIDTH(comp) (DISP_COLOR_START(comp) + 0x50)
+#define DISP_COLOR_HEIGHT(comp) (DISP_COLOR_START(comp) + 0x54)
#define DISP_AAL_EN 0x0000
#define DISP_AAL_SIZE 0x0030
@@ -107,15 +108,15 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc)
{
- writel(w, comp->regs + DISP_COLOR_WIDTH);
- writel(h, comp->regs + DISP_COLOR_HEIGHT);
+ writel(w, comp->regs + DISP_COLOR_WIDTH(comp));
+ writel(h, comp->regs + DISP_COLOR_HEIGHT(comp));
}
static void mtk_color_start(struct mtk_ddp_comp *comp)
{
writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
comp->regs + DISP_COLOR_CFG_MAIN);
- writel(0x1, comp->regs + DISP_COLOR_START);
+ writel(0x1, comp->regs + DISP_COLOR_START(comp));
}
static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
@@ -264,6 +265,16 @@ struct mtk_ddp_comp_match {
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
};
+static const struct mtk_ddp_comp_driver_data mt8173_color_driver_data = {
+ .color_offset = DISP_COLOR_START_MT8173,
+};
+
+static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
+ { .compatible = "mediatek,mt8173-disp-color",
+ .data = &mt8173_color_driver_data},
+ {},
+};
+
int mtk_ddp_comp_get_id(struct device_node *node,
enum mtk_ddp_comp_type comp_type)
{
@@ -286,6 +297,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
enum mtk_ddp_comp_type type;
struct device_node *larb_node;
struct platform_device *larb_pdev;
+ const struct of_device_id *match;
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL;
@@ -310,6 +322,11 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
type = mtk_ddp_matches[comp_id].type;
+ if (type == MTK_DISP_COLOR) {
+ match = of_match_node(mtk_disp_color_driver_dt_match, node);
+ comp->data = match->data;
+ }
+
/* Only DMA capable components need the LARB property */
comp->larb_dev = NULL;
if (type != MTK_DISP_OVL &&
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 22a33ee..cfaa760 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -78,6 +78,10 @@ struct mtk_ddp_comp_funcs {
struct drm_crtc_state *state);
};
+struct mtk_ddp_comp_driver_data {
+ unsigned int color_offset;
+};
+
struct mtk_ddp_comp {
struct clk *clk;
void __iomem *regs;
@@ -85,6 +89,7 @@ struct mtk_ddp_comp {
struct device *larb_dev;
enum mtk_ddp_comp_id id;
const struct mtk_ddp_comp_funcs *funcs;
+ const struct mtk_ddp_comp_driver_data *data;
};
static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cf83f65..5f9b5e8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -126,7 +126,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
.atomic_commit = mtk_atomic_commit,
};
-static const enum mtk_ddp_comp_id mtk_ddp_main[] = {
+static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
DDP_COMPONENT_OVL0,
DDP_COMPONENT_COLOR0,
DDP_COMPONENT_AAL,
@@ -137,7 +137,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
DDP_COMPONENT_PWM0,
};
-static const enum mtk_ddp_comp_id mtk_ddp_ext[] = {
+static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
DDP_COMPONENT_OVL1,
DDP_COMPONENT_COLOR1,
DDP_COMPONENT_GAMMA,
@@ -145,6 +145,13 @@ static int mtk_atomic_commit(struct drm_device *drm,
DDP_COMPONENT_DPI0,
};
+static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
+ .main_path = mt8173_mtk_ddp_main,
+ .main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
+ .ext_path = mt8173_mtk_ddp_ext,
+ .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
+};
+
static int mtk_drm_kms_init(struct drm_device *drm)
{
struct mtk_drm_private *private = drm->dev_private;
@@ -187,17 +194,19 @@ static int mtk_drm_kms_init(struct drm_device *drm)
* and each statically assigned to a crtc:
* OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
*/
- ret = mtk_drm_crtc_create(drm, mtk_ddp_main, ARRAY_SIZE(mtk_ddp_main));
+ ret = mtk_drm_crtc_create(drm, private->data->main_path,
+ private->data->main_len);
if (ret < 0)
goto err_component_unbind;
/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
- ret = mtk_drm_crtc_create(drm, mtk_ddp_ext, ARRAY_SIZE(mtk_ddp_ext));
+ ret = mtk_drm_crtc_create(drm, private->data->ext_path,
+ private->data->ext_len);
if (ret < 0)
goto err_component_unbind;
/* Use OVL device for all DMA memory allocations */
- np = private->comp_node[mtk_ddp_main[0]] ?:
- private->comp_node[mtk_ddp_ext[0]];
+ np = private->comp_node[private->data->main_path[0]] ?:
+ private->comp_node[private->data->ext_path[0]];
pdev = of_find_device_by_node(np);
if (!pdev) {
ret = -ENODEV;
@@ -362,6 +371,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
mutex_init(&private->commit.lock);
INIT_WORK(&private->commit.work, mtk_atomic_work);
+ private->data = of_device_get_match_data(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
private->config_regs = devm_ioremap_resource(dev, mem);
@@ -512,7 +522,8 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
mtk_drm_sys_resume);
static const struct of_device_id mtk_drm_of_ids[] = {
- { .compatible = "mediatek,mt8173-mmsys", },
+ { .compatible = "mediatek,mt8173-mmsys",
+ .data = &mt8173_mmsys_driver_data},
{ }
};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index aa93894..fa0b106 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -28,6 +28,13 @@
struct drm_property;
struct regmap;
+struct mtk_mmsys_driver_data {
+ const enum mtk_ddp_comp_id *main_path;
+ unsigned int main_len;
+ const enum mtk_ddp_comp_id *ext_path;
+ unsigned int ext_len;
+};
+
struct mtk_drm_private {
struct drm_device *drm;
struct device *dma_dev;
@@ -40,6 +47,7 @@ struct mtk_drm_private {
void __iomem *config_regs;
struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
+ const struct mtk_mmsys_driver_data *data;
struct {
struct drm_atomic_state *state;
diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index 1c366f8..c4a0165 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -16,6 +16,7 @@
#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>
@@ -87,6 +88,9 @@
#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)
@@ -123,10 +127,15 @@
#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;
unsigned int data_rate;
+ const struct mtk_mipitx_data *driver_data;
struct clk_hw pll_hw;
struct clk *pll;
};
@@ -243,6 +252,10 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
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;
}
@@ -255,6 +268,9 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
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,
@@ -391,6 +407,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
if (!mipi_tx)
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)) {
@@ -448,8 +465,13 @@ static int mtk_mipi_tx_remove(struct platform_device *pdev)
return 0;
}
+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,mt8173-mipi-tx", },
+ { .compatible = "mediatek,mt8173-mipi-tx",
+ .data = &mt8173_mipitx_data },
{},
};
--
1.9.1
^ permalink raw reply related
* [PATCH v10 01/13] drm/mediatek: add helpers for coverting from the generic components
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480070076-6196-1-git-send-email-yt.shen@mediatek.com>
define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_ovl'
define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_rdma'
Signed-off-by: YT Shen <yt.shen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 15 +++++++++------
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 15 +++++++++------
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 019b7ca..17971e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -57,6 +57,11 @@ struct mtk_disp_ovl {
struct drm_crtc *crtc;
};
+static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
+{
+ return container_of(comp, struct mtk_disp_ovl, ddp_comp);
+}
+
static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
{
struct mtk_disp_ovl *priv = dev_id;
@@ -76,19 +81,17 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
struct drm_crtc *crtc)
{
- struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
- ddp_comp);
+ struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
- priv->crtc = crtc;
+ ovl->crtc = crtc;
writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
}
static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
{
- struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
- ddp_comp);
+ struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
- priv->crtc = NULL;
+ ovl->crtc = NULL;
writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 0df05f9..21eff6f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -49,6 +49,11 @@ struct mtk_disp_rdma {
struct drm_crtc *crtc;
};
+static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
+{
+ return container_of(comp, struct mtk_disp_rdma, ddp_comp);
+}
+
static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
{
struct mtk_disp_rdma *priv = dev_id;
@@ -77,20 +82,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, unsigned int reg,
static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
struct drm_crtc *crtc)
{
- struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
- ddp_comp);
+ struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
- priv->crtc = crtc;
+ rdma->crtc = crtc;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
RDMA_FRAME_END_INT);
}
static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
{
- struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
- ddp_comp);
+ struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
- priv->crtc = NULL;
+ rdma->crtc = NULL;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
}
--
1.9.1
^ permalink raw reply related
* [PATCH v10 00/13] MT2701 DRM support
From: YT Shen @ 2016-11-25 10:34 UTC (permalink / raw)
To: linux-arm-kernel
This is MT2701 DRM support PATCH v10, based on 4.9-rc1.
We add DSI interrupt control, transfer function for MIPI DSI panel support.
Most codes are the same, except some register changed.
For example:
- DISP_OVL address offset changed, color format definition changed.
- DISP_RDMA fifo size changed.
- DISP_COLOR offset changed.
- MIPI_TX setting changed.
We add a new component DDP_COMPONENT_BLS, and the connections are updated.
OVL -> RDMA -> COLOR -> BLS -> DSI
RDMA -> DPI
And we have shadow register support in MT2701.
We remove dts patch from the patch series, which depends on MT2701 CCF and scpsys.
Changes since v9:
- Split DSI patches into smaller parts
- Use a real linux errno for return value
- Add error handling in mtk_output_dsi_enable()
- Remove unused changes and redundant delays
- Add helpers and macros for configuration
- Combine "drm/mediatek: rename macros, add chip prefix" and "drm/mediatek: add *driver_data for different hardware setting"
Changes since v8:
- enable 3 DSI interrupts only
- move mtk_dsi_wait_for_irq_done() to the patch of irq control
- use the name BLS in DRM driver part
- move BLS declaration to a separate patch
- update mtk_dsi_switch_to_cmd_mode()
- update mtk_output_dsi_enable() and mtk_output_dsi_disable()
Changes since v7:
- Remove redundant codes
- Move the definition of DDP_COMPONENT_BLS to patch of "drm/mediatek: update display module connections"
- Move _dsi_irq_wait_queue into platform driver data
- Move mtk_dsi_irq_data_clear() to patch of "drm/mediatek: add dsi interrupt control"
- Add more descriptions in the commit messages
Changes since v6:
- Change data type of irq_data to u32
- Rewrite mtk_dsi_host_transfer() for simplify
- Move some MIPI_TX config to patch of "drm/mediatek: add *driver_data for different hardware settings".
- Remove device tree from this patch series
Changes since v5:
- Remove DPI device tree and compatible string
- Use one wait queue to handle interrupt status
- Update the interrupt check flow and DSI_INT_ALL_BITS
- Use same function for host read/write command
- various fixes
Changes since v4:
- Add messages when timeout in mtk_disp_mutex_acquire()
- Add descriptions for DISP_REG_MUTEX registers
- Move connection settings for display modules to a separate patch
- Remove 'mt2701-disp-wdma' because it is unused
- Move cleaning up and renaming to a separate patch
- Use wait_event_interruptible_timeout() to replace polling
- Remove irq_num from mtk_dsi structure
- Remove redundant and debug codes
Changes since v3:
- Add DSI support for MIPI DSI panels
- Update BLS binding to PWM nodes
- Remove ufoe device nodes
- Remove redundant parentheses
- Remove global variable initialization
Changes since v2:
- Rename mtk_ddp_mux_sel to mtk_ddp_sout_sel
- Update mt2701_mtk_ddp_ext components
- Changed to prefix naming
- Reorder the patch series
- Use of_device_get_match_data() to get driver private data
- Use iopoll macros to implement mtk_disp_mutex_acquire()
- Removed empty device tree nodes
Changes since v1:
- Removed BLS bindings and codes, which belong to pwm driver
- Moved mtk_disp_mutex_acquire() just before mtk_crtc_ddp_config()
- Split patch into smaller parts
- Added const keyword to constant structure
- Removed codes for special memory align
Thanks,
yt.shen
YT Shen (11):
drm/mediatek: add helpers for coverting from the generic components
drm/mediatek: add *driver_data for different hardware settings
drm/mediatek: add shadow register support
drm/mediatek: add BLS component
drm/mediatek: update display module connections
drm/mediatek: cleaning up and refine
drm/mediatek: add mipi_tx data rate check
drm/mediatek: add dsi ulp mode control
drm/mediatek: add dsi rxtx control
drm/mediatek: update DSI sub driver flow for sending commands to panel
drm/mediatek: add support for Mediatek SoC MT2701
shaoming chen (2):
drm/mediatek: add dsi interrupt control
drm/mediatek: add dsi transfer function
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 64 +++--
drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 39 ++-
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 76 +++--
drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 138 ++++++---
drivers/gpu/drm/mediatek/mtk_drm_ddp.h | 2 +
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 41 ++-
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 7 +
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 54 +++-
drivers/gpu/drm/mediatek/mtk_drm_drv.h | 9 +
drivers/gpu/drm/mediatek/mtk_dsi.c | 430 ++++++++++++++++++++++++----
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 42 ++-
11 files changed, 737 insertions(+), 165 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH v2] mtd: nand: mxc: Fix mxc_v1 ooblayout
From: Boris Brezillon @ 2016-11-25 10:32 UTC (permalink / raw)
To: linux-arm-kernel
Commit a894cf6c5a82 ("mtd: nand: mxc: switch to mtd_ooblayout_ops")
introduced a bug in the OOB layout description. Even if the driver claims
that 3 ECC bytes are reserved to protect 512 bytes of data, it's actually
5 ECC bytes to protect 512+6 bytes of data (some OOB bytes are also
protected using extra ECC bytes).
Fix the mxc_v1_ooblayout_{free,ecc}() functions to reflect this behavior.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Fixes: a894cf6c5a82 ("mtd: nand: mxc: switch to mtd_ooblayout_ops")
Cc: <stable@vger.kernel.org>
---
Changes in v2:
- Use a macro for the number of ECC bytes
---
drivers/mtd/nand/mxc_nand.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 61ca020c5272..d929111b5ebe 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -877,6 +877,8 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
}
}
+#define MXC_V1_ECCBYTES 5
+
static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
@@ -886,7 +888,7 @@ static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
return -ERANGE;
oobregion->offset = (section * 16) + 6;
- oobregion->length = nand_chip->ecc.bytes;
+ oobregion->length = MXC_V1_ECCBYTES;
return 0;
}
@@ -908,8 +910,7 @@ static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section,
oobregion->length = 4;
}
} else {
- oobregion->offset = ((section - 1) * 16) +
- nand_chip->ecc.bytes + 6;
+ oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6;
if (section < nand_chip->ecc.steps)
oobregion->length = (section * 16) + 6 -
oobregion->offset;
--
2.7.4
^ permalink raw reply related
* [PATCH v6 3/5] ARM: dts: sun8i-h3: add HDMI video nodes
From: Icenowy Zheng @ 2016-11-25 10:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161125112213.83420594eb435b6bb1a4d164@free.fr>
25.11.2016, 18:22, "Jean-Francois Moine" <moinejf@free.fr>:
> On Fri, 25 Nov 2016 17:41:51 +0800
> Icenowy Zheng <icenowy@aosc.xyz> wrote:
>
>> ?After removing CLK_PLL_DE's assigned-clock, the kernel passes compilation.
>
> The 'pll-de' and 'de' must have a fixed rate. Otherwise, if you do not
> use the legacy u-boot, I don't know which can be the rate of the DE.
Can't CCU deal with this?
I still kept the CLK_DE's assigned-clock...
>
>> ?However, it cannot recognize any HDMI screen...
>>
>> ?(My board is Orange Pi One, and I manually added status="okay"; to &lcd0, &de, &hdmi)
>>
>> ?[ 16.507802] sun8i-de2 1000000.de-controller: bound 1c0c000.lcd-controller (ops de2_lcd_ops [sun8i_de2_drm])
>> ?[ 16.675948] sun8i-de2 1000000.de-controller: bound 1ee0000.hdmi (ops de2_hdmi_fini [sun8i_de2_hdmi])
>> ?[ 16.685120] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> ?[ 16.695876] [drm] No driver support for vblank timestamp query.
>> ?[ 16.701862] sun8i-de2 1000000.de-controller: No connectors reported connected with modes
>> ?[ 16.713061] [drm] Cannot find any crtc or sizes - going 1024x768
>> ?[ 16.734214] Console: switching to colour frame buffer device 128x48
>> ?[ 16.751022] sun8i-de2 1000000.de-controller: fb0: frame buffer device
>
> I put a 'pr_warn' message is case the EDID cannot be read.
> Have you this message?
Seems no...
>
> Anyway, there is a problem with the EDID:
> - my Orange Pi 2 (H3) randomly fails to read it. But this succeeds after
> ??rebooting once or twice.
> - my Banana Pi M2+ (H3) reads it correctly each time.
> - my Banana Pi M3 (A83T) can never read it.
>
> BTW, on first tries, I was forcing a CEA mode thru the kernel command
> line. This was working with the OPi2 and BPiM3, but there was no sound.
> In the last version, I use a EDID in edid_firmware for having sound
> with the BPiM3. This works fine.
> But, forcing a CEA mode is no more possible, so, when the OPi2 cannot
> read the EDID, the system switches to a VGA mode (default 1024x768)
> which is not supported. It seems that this is your case.
>
> So, in brief, if your board cannot read the EDID, put a EDID somewhere
> and its path in /sys/module/drm_kms_helper/parameters/edid_firmware.
> There will be no console, but X11 will work correctly.
The problem seems to be that the CRTC is not properly initialized...
>
> --
> Ken ar c'henta? | ** Breizh ha Linux atav! **
> Jef | http://moinejf.free.fr/
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox