From: Kever Yang <kever.yang@rock-chips.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/6] arm64: rk3399: add ddr controller driver
Date: Mon, 13 Feb 2017 15:52:46 +0800 [thread overview]
Message-ID: <58A165CE.7020801@rock-chips.com> (raw)
In-Reply-To: <CAPnjgZ1vHHodCy2d_WJ05-tkMhJv5HBbPDoCShHnL484btL1Ng@mail.gmail.com>
Hi Simon,
On 02/08/2017 01:10 PM, Simon Glass wrote:
> +Tom in case you have some thoughts
>
> Hi Kever,
>
> On 4 February 2017 at 18:45, Kever Yang <kever.yang@rock-chips.com> wrote:
>> Hi Simon,
>>
>> On 01/26/2017 10:23 PM, Simon Glass wrote:
>>> Hi Kever,
>>>
>>> On 18 January 2017 at 05:16, Kever Yang <kever.yang@rock-chips.com> wrote:
>>>> RK3399 support DDR3, LPDDR3, DDR4 sdram, this patch is porting from
>>>> coreboot, support 4GB lpddr3 in this version.
>>>>
>>>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>>>> ---
>>>>
>>>> arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi | 1536
>>>> +++++++++++++++++++++
>>>> arch/arm/include/asm/arch-rockchip/sdram_rk3399.h | 120 ++
>>>> arch/arm/mach-rockchip/rk3399/Makefile | 1 +
>>>> arch/arm/mach-rockchip/rk3399/sdram_rk3399.c | 1243
>>>> +++++++++++++++++
>>>> 4 files changed, 2900 insertions(+)
>>>> create mode 100644 arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>>>> create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
>>>> create mode 100644 arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
>>>>
>>> Change log?
>>
>> Sorry for missing change log, basically, I apply all the comments from you
>> but
>> MASK/SHIFT.
>>
>>> Re your comments about MASK/SHIFT and register definitions, I'm not
>>> convinced. In my case I set up a Python script to create the registers
>>> (with the MASK set incorrectly unfortunately) and did something like
>>> this:
>>>
>>> pdftotext -layout -f 130 -l 350 rk3288-fs.pdf /tmp/asc
>>> tools/rkmux.py /tmp/asc GRF_GPIO4C_IOMUX
>>>
>>> to generate the definitions. Does that help?
>>
>> Is not only header file need to update, but also almost all the register
>> operation in C source code.
> Yes that's right.
>
>>>
>>> My concern is that if we don't write a good quality driver now, when
>>> will it be updated/fixed? It seems better to do it now. Is it really a
>>> lot of work?
>>
>> I agree that we should write a good quality driver, but it does not mean
>> the quality is not good if I don't include SHIFT in MASK, right?
>> I would like to include the SHIFT in MASK if this is the first time for
>> the driver commit to public as the requirement from maintainer,
>> but this is porting from coreboot which has prove to be a good quality
>> driver
>> with a lot of test.
>> Another point is that in order to make it easier to maintain the source
>> code,
>> we have already sync our internal source code to the copy on coreboot, it's
>> really not convenient for the driver owner(not me, there are other guys
>> focus
>> on dram drivers) to maintain all these drivers in different platform.
>> And here comes another question, what should we do for next SoC driver
>> if we need to upstream the driver to coreboot and U-Boot, and maybe UEFI,
>> make totally different format version for different platform? I think try to
>> convince some of the maintainer should be the best choice and then we can
>> focus on maintain the same one copy of source code, right?
>>
>> Back to U-Boot, I don't the format of MASK is so important, just like no
>> more
>> than 80-bytes in one line in coding style, we should consider to accept it
>> if
>> there are some reason. There are also many MASKs in U-Boot drivers without
>> SHIFT in it, I wouldn't say which kind is better, but U-Boot can say prefer
>> to
>> use MASKs with SHIFT, but please don't refuse everything other than that.
> Well we can leave the MASK to not include the SHIFT. That was my
> mistake originally so perhaps I should clean it up.
Thanks very much.
>
> But this sort of thing:
>
>> +#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + ((ch) * 16)))
>> +#define SYS_REG_DEC_DBW(n, ch) (2 >> ((n >> (0 + 16 * ch)) & 0x3))
> is really not nice IMO, particularly for something that is only used
> once in the C code. Does coreboot actually require this style, or
> could it use the more explicit SHIFT/MASK used like U-Boot?
The sys_reg is for record dram size info, also appear in rk3288,
this change is intent to make easier to read the C source code,
I will update this blob of code back to the style like rk3288 dram driver.
>
> I do understand the problem of multiple platforms but in general each
> project has its own code style and we try to stick to it. U-Boot
> follows kernel style pretty closely, but it is try that SHIFT/MASK
> things are much more common in U-Boot than Linux since it sets up
> hardware.
>
> Re keeping the drivers in sync, yes it is a pain. But I hope that it
> becomes easier to maintain. There is a pretty big user community
> around U-Boot, and Rockchip is a popular chip. So I'm trying to keep
> it as a good example of how to do things.
>
> So I'd really like to change this.
>
> Regards,
> Simon
>
>> Thanks,
>> - Kever
>>
>>
>>>> diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>>>> b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>>>> new file mode 100644
>>>> index 0000000..5568be2
>>>> --- /dev/null
>>>> +++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
>>>> @@ -0,0 +1,1536 @@
>>>> +/*
>>>> + * (C) Copyright 2016 Rockchip Electronics Co., Ltd
>>>> + *
>>>> + * SPDX-License-Identifier: GPL-2.0+
>>>> + */
>>>> +
>>>> +&dmc {
>>>> + rockchip,sdram-params = <
>>>> + 0x2
>>>> + 0xA
>>> Can you use lower-case hex please?
Will update.
>>>
>>>> + 0x3
>>>> + 0x2
>>>> + 0x2
>>>> + 0x0
>>> ...
>>>
>>>> +#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
>>>> +#define SYS_REG_DEC_ROW_3_4(n, ch) ((n >> (30 + ch)) & 0x1)
>>>> +#define SYS_REG_ENC_CHINFO(ch) (1 << (28 + (ch)))
>>>> +#define SYS_REG_ENC_DDRTYPE(n) ((n) << 13)
>>>> +#define SYS_REG_ENC_NUM_CH(n) (((n) - 1) << 12)
>>>> +#define SYS_REG_DEC_NUM_CH(n) (1 + ((n >> 12) & 0x1))
>>>> +#define SYS_REG_ENC_RANK(n, ch) (((n) - 1) << (11 + ((ch)
>>>> * 16)))
>>>> +#define SYS_REG_DEC_RANK(n, ch) (1 + ((n >> (11 + 16 *
>>>> ch)) & 0x1))
>>>> +#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << (9 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_COL(n, ch) (9 + ((n >> (9 + 16 * ch)) &
>>>> 0x3))
>>>> +#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) \
>>>> + << (8 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_BK(n, ch) (3 - ((n >> (8 + 16 * ch)) &
>>>> 0x1))
>>>> +#define SYS_REG_ENC_CS0_ROW(n, ch) (((n) - 13) << (6 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_CS0_ROW(n, ch) (13 + ((n >> (6 + 16 * ch)) &
>>>> 0x3))
>>>> +#define SYS_REG_ENC_CS1_ROW(n, ch) (((n) - 13) << (4 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_CS1_ROW(n, ch) (13 + ((n >> (4 + 16 * ch)) &
>>>> 0x3))
>>>> +#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << (2 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_BW(n, ch) (2 >> ((n >> (2 + 16 * ch)) &
>>>> 0x3))
>>>> +#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + ((ch) * 16)))
>>>> +#define SYS_REG_DEC_DBW(n, ch) (2 >> ((n >> (0 + 16 * ch)) &
>>>> 0x3))
>>> These seem impenetrable to me :-( Is this the coreboot code standard?
Will update.
>>>
>>>> +
>>>> +#define DDR_STRIDE(n, r) writel((0x1F << (10 + 16)) \
>>>> + | (n << 10), r)
>>> This is only used one, so can you just inline it?
Will remove this Macro and use C directly.
>>>
>>>> +
>>>> +#define PRESET_SGRF_HOLD(n) ((0x1 << (6+16)) | ((n) << 6))
>>>> +#define PRESET_GPIO0_HOLD(n) ((0x1 << (7+16)) | ((n) << 7))
>>>> +#define PRESET_GPIO1_HOLD(n) ((0x1 << (8+16)) | ((n) << 8))
>>>> +
>>>> +#define PHY_DRV_ODT_Hi_Z (0x0)
>>> Drop () on these simple constants.
Will update.
>>>
>>>> +#define PHY_DRV_ODT_240 (0x1)
>>>> +#define PHY_DRV_ODT_120 (0x8)
>>>> +#define PHY_DRV_ODT_80 (0x9)
>>>> +#define PHY_DRV_ODT_60 (0xc)
>>>> +#define PHY_DRV_ODT_48 (0xd)
>>>> +#define PHY_DRV_ODT_40 (0xe)
>>>> +#define PHY_DRV_ODT_34_3 (0xf)
>>>> +
>>>> +#ifdef CONFIG_SPL_BUILD
>>>> +
>>>> +struct rockchip_dmc_plat {
>>>> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
>>>> + struct dtd_rockchip_rk3399_dmc dtplat;
>>>> +#endif
>>>> + struct regmap *map;
>>>> +};
>>>> +
>>>> +static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
>>>> +{
>>>> + int i;
>>>> +
>>>> + for (i = 0; i < n / sizeof(u32); i++) {
>>>> + writel(*src, dest);
>>>> + src++;
>>>> + dest++;
>>>> + }
>>>> +}
>>>> +
>>>> +static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs
>>>> *ddr_publ_regs,
>>>> + u32 freq)
>>>> +{
>>>> + u32 *denali_phy = ddr_publ_regs->denali_phy;
>>>> +
>>>> + if (freq <= 125) {
>>> Please add a comment as to why 125 is the magic number.
Will update.
>>>
>>>> + /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8
>>>> */
>>>> + setbits_le32(&denali_phy[86], (0x3 << 2) << 8);
>>>> + setbits_le32(&denali_phy[214], (0x3 << 2) << 8);
>>>> + setbits_le32(&denali_phy[342], (0x3 << 2) << 8);
>>>> + setbits_le32(&denali_phy[470], (0x3 << 2) << 8);
>>>> +
>>>> + /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits
>>>> offset_16 */
>>>> + setbits_le32(&denali_phy[547], (0x3 << 2) << 16);
>>>> + setbits_le32(&denali_phy[675], (0x3 << 2) << 16);
>>>> + setbits_le32(&denali_phy[803], (0x3 << 2) << 16);
>>>> + } else {
>>>> + /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8
>>>> */
>>>> + clrbits_le32(&denali_phy[86], (0x3 << 2) << 8);
>>>> + clrbits_le32(&denali_phy[214], (0x3 << 2) << 8);
>>>> + clrbits_le32(&denali_phy[342], (0x3 << 2) << 8);
>>>> + clrbits_le32(&denali_phy[470], (0x3 << 2) << 8);
>>>> +
>>>> + /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits
>>>> offset_16 */
>>>> + clrbits_le32(&denali_phy[547], (0x3 << 2) << 16);
>>>> + clrbits_le32(&denali_phy[675], (0x3 << 2) << 16);
>>>> + clrbits_le32(&denali_phy[803], (0x3 << 2) << 16);
>>>> + }
>>>> +}
>>>> +
>>>> +static void set_memory_map(const struct chan_info *chan, u32 channel,
>>>> + const struct rk3399_sdram_params
>>>> *sdram_params)
>>>> +{
>>>> + const struct rk3399_sdram_channel *sdram_ch =
>>>> + &sdram_params->ch[channel];
>>>> + u32 *denali_ctl = chan->pctl->denali_ctl;
>>>> + u32 *denali_pi = chan->pi->denali_pi;
>>>> + u32 cs_map;
>>>> + u32 reduc;
>>>> + u32 row;
>>>> +
>>>> + /* Get row number from ddrconfig setting */
>>>> + if ((sdram_ch->ddrconfig < 2) || (sdram_ch->ddrconfig == 4))
>>> nit: too many brackets
Will update.
>>>
>>>> + row = 16;
>>>> + else if (sdram_ch->ddrconfig == 3)
>>>> + row = 14;
>>>> + else
>>>> + row = 15;
>>>> +
>>>> + cs_map = (sdram_ch->rank > 1) ? 3 : 1;
>>>> + reduc = (sdram_ch->bw == 2) ? 0 : 1;
>>>> +
>>>> + clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col));
>>>> + clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
>>>> + ((3 - sdram_ch->bk) << 16) |
>>>> + ((16 - row) << 24));
>>> What are all these magic numbers? Shouldn't there be register names in
>>> denali_ctl, i.e have it as a struct instead of 191, 190?
Will update the comment, there is no register name in IP spec.
Thanks,
- Kever
>>>
>>>> + clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
>>>> + clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
>>>> + clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
>>>> + clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
>>>> +
>>>> + /*
>>>> + * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
>>>> + * sets termination values for read/idle cycles and drive
>>>> strength
>>>> + * for write cycles for DQS
>>>> + */
>>> ...
>>>
>>> Regards,
>>> Simon
>>>
>>>
>>>
>>
>
>
next prev parent reply other threads:[~2017-02-13 7:52 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-18 12:16 [U-Boot] [PATCH 0/6] rk3399: enable SPL driver Kever Yang
2017-01-18 12:16 ` [U-Boot] [PATCH 1/6] arm64: rk3399: add ddr controller driver Kever Yang
2017-01-26 14:23 ` Simon Glass
2017-02-05 2:45 ` Kever Yang
2017-02-08 5:10 ` Simon Glass
2017-02-13 7:52 ` Kever Yang [this message]
2017-01-18 12:16 ` [U-Boot] [PATCH 2/6] arm64: rk3399: move grf register definitions to grf_rk3399.h Kever Yang
2017-01-25 4:09 ` Simon Glass
2017-01-18 12:16 ` [U-Boot] [PATCH 3/6] clk: rk3399: update driver for spl Kever Yang
2017-01-26 14:23 ` Simon Glass
2017-01-18 12:16 ` [U-Boot] [PATCH 4/6] sdhci: rk3399: update driver to support of-platdata Kever Yang
2017-01-26 14:23 ` Simon Glass
2017-01-18 12:16 ` [U-Boot] [PATCH 5/6] pinctrl: rk3399: add the of-platdata support Kever Yang
2017-01-26 14:23 ` Simon Glass
2017-01-18 12:16 ` [U-Boot] [PATCH 6/6] arm64: rk3399: add SPL support Kever Yang
2017-01-26 14:23 ` Simon Glass
2017-02-05 3:01 ` Kever Yang
2017-02-08 5:10 ` Simon Glass
2017-01-24 13:51 ` [U-Boot] [PATCH 0/6] rk3399: enable SPL driver Simon Glass
2017-02-05 1:41 ` Kever Yang
2017-02-08 5:10 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=58A165CE.7020801@rock-chips.com \
--to=kever.yang@rock-chips.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox