[PATCH v6 5/9] drm/hisilicon/hibmc: Add crtc for DE
Sean Paul
seanpaul at chromium.org
Mon Nov 14 09:10:56 PST 2016
On Sat, Nov 12, 2016 at 5:19 AM, Rongrong Zou <zourongrong at huawei.com> wrote:
> 在 2016/11/11 6:14, Sean Paul 写道:
>>
>> On Fri, Oct 28, 2016 at 3:27 AM, Rongrong Zou <zourongrong at gmail.com>
>> wrote:
>>>
>>> Add crtc funcs and helper funcs for DE.
>>>
>>> Signed-off-by: Rongrong Zou <zourongrong at gmail.com>
>>> ---
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 318
>>> ++++++++++++++++++++++++
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 6 +
>>> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 +
>>> 3 files changed, 326 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
>>> index 9c1a68c..9b5d0d0 100644
>>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
>>> @@ -23,6 +23,7 @@
>>>
>>> #include "hibmc_drm_drv.h"
>>> #include "hibmc_drm_regs.h"
>>> +#include "hibmc_drm_de.h"
>>> #include "hibmc_drm_power.h"
>>
>>
>> nit: alphabetize
>
>
> ok, thanks.
>
>>
>>>
>>> /*
>>> ---------------------------------------------------------------------- */
>>
>>
>> Remove
>
>
> will do, thanks.
>
>>
>>> @@ -168,3 +169,320 @@ int hibmc_plane_init(struct hibmc_drm_device
>>> *hidev)
>>> drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
>>> return 0;
>>> }
>>> +
>>> +static void hibmc_crtc_enable(struct drm_crtc *crtc)
>>> +{
>>> + unsigned int reg;
>>> + /* power mode 0 is default. */
>>
>>
>> This comment seems to be in the wrong place
>
>
> will remove it, thanks.
>
>
>>
>>> + struct hibmc_drm_device *hidev = crtc->dev->dev_private;
>>> +
>>> + hibmc_set_power_mode(hidev, HIBMC_PW_MODE_CTL_MODE_MODE0);
>>> +
>>> + /* Enable display power gate & LOCALMEM power gate*/
>>> + reg = readl(hidev->mmio + HIBMC_CURRENT_GATE);
>>> + reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
>>> + reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
>>> + reg |= HIBMC_CURR_GATE_LOCALMEM(ON);
>>> + reg |= HIBMC_CURR_GATE_DISPLAY(ON);
>>> + hibmc_set_current_gate(hidev, reg);
>>> + drm_crtc_vblank_on(crtc);
>>> +}
>>> +
>>> +static void hibmc_crtc_disable(struct drm_crtc *crtc)
>>> +{
>>> + unsigned int reg;
>>> + struct hibmc_drm_device *hidev = crtc->dev->dev_private;
>>> +
>>> + drm_crtc_vblank_off(crtc);
>>> +
>>> + hibmc_set_power_mode(hidev, HIBMC_PW_MODE_CTL_MODE_SLEEP);
>>> +
>>> + /* Enable display power gate & LOCALMEM power gate*/
>>> + reg = readl(hidev->mmio + HIBMC_CURRENT_GATE);
>>> + reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
>>> + reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
>>> + reg |= HIBMC_CURR_GATE_LOCALMEM(OFF);
>>> + reg |= HIBMC_CURR_GATE_DISPLAY(OFF);
>>> + hibmc_set_current_gate(hidev, reg);
>>> +}
>>> +
>>> +static int hibmc_crtc_atomic_check(struct drm_crtc *crtc,
>>> + struct drm_crtc_state *state)
>>> +{
>>> + return 0;
>>> +}
>>
>>
>> Caller NULL-checks, no need for stub
>
>
> thanks for pointing it out.
>
>
>>
>>> +
>>> +static unsigned int format_pll_reg(void)
>>> +{
>>> + unsigned int pllreg = 0;
>>> + struct panel_pll pll = {0};
>>> +
>>> + /* Note that all PLL's have the same format. Here,
>>> + * we just use Panel PLL parameter to work out the bit
>>> + * fields in the register.On returning a 32 bit number, the value
>>> can
>>> + * be applied to any PLL in the calling function.
>>> + */
>>> + pllreg |= HIBMC_PLL_CTRL_BYPASS(OFF) &
>>> HIBMC_PLL_CTRL_BYPASS_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_POWER(ON) & HIBMC_PLL_CTRL_POWER_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_INPUT(OSC) & HIBMC_PLL_CTRL_INPUT_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_POD(pll.POD) & HIBMC_PLL_CTRL_POD_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_OD(pll.OD) & HIBMC_PLL_CTRL_OD_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_N(pll.N) & HIBMC_PLL_CTRL_N_MASK;
>>> + pllreg |= HIBMC_PLL_CTRL_M(pll.M) & HIBMC_PLL_CTRL_M_MASK;
>>> +
>>> + return pllreg;
>>> +}
>>> +
>>> +static void set_vclock_hisilicon(struct drm_device *dev, unsigned long
>>> pll)
>>> +{
>>> + unsigned long tmp0, tmp1;
>>> + struct hibmc_drm_device *hidev = dev->dev_private;
>>> +
>>> + /* 1. outer_bypass_n=0 */
>>> + tmp0 = readl(hidev->mmio + CRT_PLL1_HS);
>>> + tmp0 &= 0xBFFFFFFF;
>>> + writel(tmp0, hidev->mmio + CRT_PLL1_HS);
>>> +
>>> + /* 2. pll_pd=1?inter_bypass=1 */
>>> + writel(0x21000000, hidev->mmio + CRT_PLL1_HS);
>>> +
>>> + /* 3. config pll */
>>> + writel(pll, hidev->mmio + CRT_PLL1_HS);
>>> +
>>> + /* 4. delay */
>>> + mdelay(1);
>>
>>
>> These should be usleep_range() see
>> https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
>
>
> This looks better to me. i think a 'usleep_range(1000, 2000)' is ok.
>
>>
>>> +
>>> + /* 5. pll_pd =0 */
>>> + tmp1 = pll & ~0x01000000;
>>> + writel(tmp1, hidev->mmio + CRT_PLL1_HS);
>>> +
>>> + /* 6. delay */
>>> + mdelay(1);
>>> +
>>> + /* 7. inter_bypass=0 */
>>> + tmp1 &= ~0x20000000;
>>> + writel(tmp1, hidev->mmio + CRT_PLL1_HS);
>>> +
>>> + /* 8. delay */
>>> + mdelay(1);
>>> +
>>> + /* 9. outer_bypass_n=1 */
>>> + tmp1 |= 0x40000000;
>>> + writel(tmp1, hidev->mmio + CRT_PLL1_HS);
>>
>>
>> This function is a whole lot of magic. Any chance you can pull the
>> values out into #defines?
>
>
> will do. thanks.
>
>>
>>> +}
>>> +
>>> +/* This function takes care the extra registers and bit fields required
>>> to
>>
>>
>> nit: multi-line comments have a leading /* line with the comment
>> starting on the following line
>
>
> thanks for pointing it out.
>
>>
>> applies below as well
>>
>>
>>> + *setup a mode in board.
>>
>>
>> nit: space between * and comment, ie: * setup a mode in board
>
>
> understood, thanks.
>
>
>>
>> applies to the rest of the comment too
>>
>>
>>> + *Explanation about Display Control register:
>>> + *FPGA only supports 7 predefined pixel clocks, and clock select is
>>> + *in bit 4:0 of new register 0x802a8.
>>> + */
>>> +static unsigned int display_ctrl_adjust(struct drm_device *dev,
>>> + struct drm_display_mode *mode,
>>> + unsigned int ctrl)
>>> +{
>>> + unsigned long x, y;
>>> + unsigned long pll1; /* bit[31:0] of PLL */
>>> + unsigned long pll2; /* bit[63:32] of PLL */
>>> + struct hibmc_drm_device *hidev = dev->dev_private;
>>> +
>>> + x = mode->hdisplay;
>>> + y = mode->vdisplay;
>>> +
>>> + /* Hisilicon has to set up a new register for PLL control
>>> + *(CRT_PLL1_HS & CRT_PLL2_HS).
>>> + */
>>> + if (x == 800 && y == 600) {
>>> + pll1 = CRT_PLL1_HS_40MHZ;
>>> + pll2 = CRT_PLL2_HS_40MHZ;
>>> + } else if (x == 1024 && y == 768) {
>>> + pll1 = CRT_PLL1_HS_65MHZ;
>>> + pll2 = CRT_PLL2_HS_65MHZ;
>>> + } else if (x == 1152 && y == 864) {
>>> + pll1 = CRT_PLL1_HS_80MHZ_1152;
>>> + pll2 = CRT_PLL2_HS_80MHZ;
>>> + } else if (x == 1280 && y == 768) {
>>> + pll1 = CRT_PLL1_HS_80MHZ;
>>> + pll2 = CRT_PLL2_HS_80MHZ;
>>> + } else if (x == 1280 && y == 720) {
>>> + pll1 = CRT_PLL1_HS_74MHZ;
>>> + pll2 = CRT_PLL2_HS_74MHZ;
>>> + } else if (x == 1280 && y == 960) {
>>> + pll1 = CRT_PLL1_HS_108MHZ;
>>> + pll2 = CRT_PLL2_HS_108MHZ;
>>> + } else if (x == 1280 && y == 1024) {
>>> + pll1 = CRT_PLL1_HS_108MHZ;
>>> + pll2 = CRT_PLL2_HS_108MHZ;
>>> + } else if (x == 1600 && y == 1200) {
>>> + pll1 = CRT_PLL1_HS_162MHZ;
>>> + pll2 = CRT_PLL2_HS_162MHZ;
>>> + } else if (x == 1920 && y == 1080) {
>>> + pll1 = CRT_PLL1_HS_148MHZ;
>>> + pll2 = CRT_PLL2_HS_148MHZ;
>>> + } else if (x == 1920 && y == 1200) {
>>> + pll1 = CRT_PLL1_HS_193MHZ;
>>> + pll2 = CRT_PLL2_HS_193MHZ;
>>> + } else /* default to VGA clock */ {
>>> + pll1 = CRT_PLL1_HS_25MHZ;
>>> + pll2 = CRT_PLL2_HS_25MHZ;
>>> + }
>>
>>
>> This seems like something that should be checked in atomic_check so
>> you can be sure the mode is supported.
>>
>> It would also be nice to pull this out into a separate function (and a
>> lookup table if you're feeling adventurous)
>
>
> a lookup table seems good, thanks.
>
>
>>
>>> +
>>> + writel(pll2, hidev->mmio + CRT_PLL2_HS);
>>> + set_vclock_hisilicon(dev, pll1);
>>> +
>>> + /* Hisilicon has to set up the top-left and bottom-right
>>> + * registers as well.
>>> + * Note that normal chip only use those two register for
>>> + * auto-centering mode.
>>> + */
>>> + writel((HIBMC_CRT_AUTO_CENTERING_TL_TOP(0) &
>>> + HIBMC_CRT_AUTO_CENTERING_TL_TOP_MSK) |
>>> + (HIBMC_CRT_AUTO_CENTERING_TL_LEFT(0) &
>>> + HIBMC_CRT_AUTO_CENTERING_TL_LEFT_MSK),
>>> + hidev->mmio + HIBMC_CRT_AUTO_CENTERING_TL);
>>> +
>>> + writel((HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM(y - 1) &
>>> + HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM_MASK) |
>>> + (HIBMC_CRT_AUTO_CENTERING_BR_RIGHT(x - 1) &
>>> + HIBMC_CRT_AUTO_CENTERING_BR_RIGHT_MASK),
>>> + hidev->mmio + HIBMC_CRT_AUTO_CENTERING_BR);
>>> +
>>> + /* Assume common fields in ctrl have been properly set before
>>> + * calling this function.
>>> + * This function only sets the extra fields in ctrl.
>>> + */
>>> +
>>> + /* Set bit 25 of display controller: Select CRT or VGA clock */
>>> + ctrl &= ~HIBMC_CRT_DISP_CTL_CRTSELECT_MASK;
>>> + ctrl &= ~HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK;
>>> +
>>> + ctrl |= HIBMC_CRT_DISP_CTL_CRTSELECT(CRTSELECT_CRT);
>>> +
>>> + /*ctrl = FIELD_SET(ctrl, HIBMC_CRT_DISP_CTL, CRTSELECT, CRT);*/
>>
>>
>> What's the deal with this commented code?
>
>
> sorry, will clean up.
>
>>
>>> +
>>> + /* Set bit 14 of display controller */
>>> + /*ctrl &= FIELD_CLEAR(HIBMC_CRT_DISP_CTL, CLOCK_PHASE);*/
>>> +
>>> + /* clock_phase_polarity is 0 */
>>> + ctrl |= HIBMC_CRT_DISP_CTL_CLOCK_PHASE(PHASE_ACTIVE_HIGH);
>>> + /*ctrl = FIELD_SET(ctrl, HIBMC_CRT_DISP_CTL,*/
>>> + /*CLOCK_PHASE, ACTIVE_HIGH);*/
>>
>>
>> Here too...
>
>
> ditto.
>
>>
>>> +
>>> + writel(ctrl, hidev->mmio + HIBMC_CRT_DISP_CTL);
>>> +
>>> + return ctrl;
>>> +}
>>> +
>>> +static void hibmc_crtc_mode_set_nofb(struct drm_crtc *crtc)
>>> +{
>>> + unsigned int val;
>>> + struct drm_display_mode *mode = &crtc->state->mode;
>>> + struct drm_device *dev = crtc->dev;
>>> + struct hibmc_drm_device *hidev = dev->dev_private;
>>> +
>>> + writel(format_pll_reg(), hidev->mmio + HIBMC_CRT_PLL_CTRL);
>>> + writel((HIBMC_CRT_HORZ_TOTAL_TOTAL(mode->htotal - 1) &
>>> + HIBMC_CRT_HORZ_TOTAL_TOTAL_MASK) |
>>> + (HIBMC_CRT_HORZ_TOTAL_DISPLAY_END(mode->hdisplay - 1) &
>>> + HIBMC_CRT_HORZ_TOTAL_DISPLAY_END_MASK),
>>
>>
>> You could probably macroize this code to make it more readable
>
>
>
> #define HIBMC_FIELD(field, value) (field(value) & filed##_MASK)
>
> writel(HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_TOTAL, mode->htotal - 1) |
> HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_DISPLAY_END, mode->hdisplay
> - 1),
> hidev->mmio + HIBMC_CRT_HORZ_TOTAL);
>
> Is above ok?
>
Seems like an improvement.
>
>
>
>>
>>> + hidev->mmio + HIBMC_CRT_HORZ_TOTAL);
>>> +
>>> + writel((HIBMC_CRT_HORZ_SYNC_WIDTH(mode->hsync_end -
>>> mode->hsync_start)
>>> + & HIBMC_CRT_HORZ_SYNC_WIDTH_MASK) |
>>> + (HIBMC_CRT_HORZ_SYNC_START(mode->hsync_start - 1)
>>> + & HIBMC_CRT_HORZ_SYNC_START_MASK),
>>> + hidev->mmio + HIBMC_CRT_HORZ_SYNC);
>>> +
>>> + writel((HIBMC_CRT_VERT_TOTAL_TOTAL(mode->vtotal - 1) &
>>> + HIBMC_CRT_VERT_TOTAL_TOTAL_MASK) |
>>> + (HIBMC_CRT_VERT_TOTAL_DISPLAY_END(mode->vdisplay - 1) &
>>> + HIBMC_CRT_VERT_TOTAL_DISPLAY_END_MASK),
>>> + hidev->mmio + HIBMC_CRT_VERT_TOTAL);
>>> +
>>> + writel((HIBMC_CRT_VERT_SYNC_HEIGHT(mode->vsync_end -
>>> mode->vsync_start)
>>> + & HIBMC_CRT_VERT_SYNC_HEIGHT_MASK) |
>>> + (HIBMC_CRT_VERT_SYNC_START(mode->vsync_start - 1) &
>>> + HIBMC_CRT_VERT_SYNC_START_MASK),
>>> + hidev->mmio + HIBMC_CRT_VERT_SYNC);
>>> +
>>> + val = HIBMC_CRT_DISP_CTL_VSYNC_PHASE(0) &
>>> + HIBMC_CRT_DISP_CTL_VSYNC_PHASE_MASK;
>>> + val |= HIBMC_CRT_DISP_CTL_HSYNC_PHASE(0) &
>>> + HIBMC_CRT_DISP_CTL_HSYNC_PHASE_MASK;
>>> + val |= HIBMC_CRT_DISP_CTL_TIMING(ENABLE);
>>> + val |= HIBMC_CRT_DISP_CTL_PLANE(ENABLE);
>>> +
>>> + display_ctrl_adjust(dev, mode, val);
>>> +}
>>> +
>>> +static void hibmc_crtc_atomic_begin(struct drm_crtc *crtc,
>>> + struct drm_crtc_state *old_state)
>>> +{
>>> + unsigned int reg;
>>> + struct drm_device *dev = crtc->dev;
>>> + struct hibmc_drm_device *hidev = dev->dev_private;
>>> +
>>> + hibmc_set_power_mode(hidev, HIBMC_PW_MODE_CTL_MODE_MODE0);
>>> +
>>> + /* Enable display power gate & LOCALMEM power gate*/
>>> + reg = readl(hidev->mmio + HIBMC_CURRENT_GATE);
>>> + reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
>>> + reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
>>> + reg |= HIBMC_CURR_GATE_DISPLAY(ON);
>>> + reg |= HIBMC_CURR_GATE_LOCALMEM(ON);
>>> + hibmc_set_current_gate(hidev, reg);
>>> +
>>> + /* We can add more initialization as needed. */
>>> +}
>>> +
>>> +static void hibmc_crtc_atomic_flush(struct drm_crtc *crtc,
>>> + struct drm_crtc_state *old_state)
>>> +
>>> +{
>>> + unsigned long flags;
>>> +
>>> + spin_lock_irqsave(&crtc->dev->event_lock, flags);
>>> + if (crtc->state->event)
>>> + drm_crtc_send_vblank_event(crtc, crtc->state->event);
>>> + crtc->state->event = NULL;
>>> +
>>> + spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
>>> +}
>>> +
>>> +/* These provide the minimum set of functions required to handle a CRTC
>>> */
>>
>>
>> nit: don't need this comment
>
>
> will delete, thanks.
>
>
>>
>>> +static const struct drm_crtc_funcs hibmc_crtc_funcs = {
>>> + .page_flip = drm_atomic_helper_page_flip,
>>> + .set_config = drm_atomic_helper_set_config,
>>> + .destroy = drm_crtc_cleanup,
>>> + .reset = drm_atomic_helper_crtc_reset,
>>> + .atomic_duplicate_state =
>>> drm_atomic_helper_crtc_duplicate_state,
>>> + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>>> +};
>>> +
>>> +static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = {
>>> + .enable = hibmc_crtc_enable,
>>> + .disable = hibmc_crtc_disable,
>>> + .mode_set_nofb = hibmc_crtc_mode_set_nofb,
>>> + .atomic_check = hibmc_crtc_atomic_check,
>>> + .atomic_begin = hibmc_crtc_atomic_begin,
>>> + .atomic_flush = hibmc_crtc_atomic_flush,
>>> +};
>>> +
>>> +int hibmc_crtc_init(struct hibmc_drm_device *hidev)
>>> +{
>>> + struct drm_device *dev = hidev->dev;
>>> + struct drm_crtc *crtc = &hidev->crtc;
>>> + struct drm_plane *plane = &hidev->plane;
>>> + int ret;
>>> +
>>> + ret = drm_crtc_init_with_planes(dev, crtc, plane,
>>> + NULL, &hibmc_crtc_funcs, NULL);
>>> + if (ret) {
>>> + DRM_ERROR("failed to init crtc.\n");
>>
>>
>> print return code
>
>
> agreed, thanks.
>
>>
>>> + return ret;
>>> + }
>>> +
>>> + drm_mode_crtc_set_gamma_size(crtc, 256);
>>
>>
>> check return code
>
>
> agreed though none of other drivers has done this,
> thanks.
>
>>
>>> + drm_crtc_helper_add(crtc, &hibmc_crtc_helper_funcs);
>>> + return 0;
>>> +}
>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>> index 7d96583..303cd36 100644
>>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
>>> @@ -119,6 +119,12 @@ static int hibmc_kms_init(struct hibmc_drm_device
>>> *hidev)
>>> return ret;
>>> }
>>>
>>> + ret = hibmc_crtc_init(hidev);
>>> + if (ret) {
>>> + DRM_ERROR("failed to init crtc.\n");
>>> + return ret;
>>> + }
>>
>>
>> Typically the plane is initialized internally in the crtc driver. I
>> think this is a good design pattern, and you should probably use it.
>>
>> So how about squashing this down with the plane patch and keeping the
>> plane inside hibmc_drm_de.c?
>
>
> understood after i looked at intel_display.c, this file will be merged
> with patch 4/9, and the tile will be: 'drm/hisilicon/hibmc: Add display
> engine'.
>
Great, thanks.
>>
>>> +
>>> return 0;
>>> }
>>>
>>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>> index 49e39d2..5731ec2 100644
>>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>>> @@ -46,6 +46,7 @@ struct hibmc_drm_device {
>>> /* drm */
>>> struct drm_device *dev;
>>> struct drm_plane plane;
>>
>>
>> I don't think you should be keeping track of plane here. plane is only
>> used in the crtc init, which should be addressed by the previous
>> comment.
>
>
> so allocate with devm_kzalloc(sizeof(*plane)) and remove it from
> hibmc_drm_device?
>
>>
>>
>>> + struct drm_crtc crtc;
>>
>>
>> crtc is only used in the irq handler, so you could remove this here
>> and just call drm_handle_vblank(dev, 0) in the handler.
>
>
> so allocate with devm_kzalloc(sizeof(*crtc)) and remove it from
> hibmc_drm_device, when driver unload drm_crtc_cleanup() will be
> called and finally memory will be freed before quit.
>
Yep, precisely.
Sean
>>
>>
>>> bool mode_config_initialized;
>>>
>>> /* ttm */
>>> @@ -85,6 +86,7 @@ static inline struct hibmc_bo *gem_to_hibmc_bo(struct
>>> drm_gem_object *gem)
>>> #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
>>>
>>> int hibmc_plane_init(struct hibmc_drm_device *hidev);
>>> +int hibmc_crtc_init(struct hibmc_drm_device *hidev);
>>> int hibmc_fbdev_init(struct hibmc_drm_device *hidev);
>>> void hibmc_fbdev_fini(struct hibmc_drm_device *hidev);
>>>
>>> --
>>> 1.9.1
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linuxarm mailing list
>> linuxarm at huawei.com
>> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm
>>
>> .
>>
>
>
> --
> Regards, Rongrong
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list