Skip to content

Upstream drm #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
515 changes: 245 additions & 270 deletions drivers/gpu/drm/hisilicon/hisi_ade.c

Large diffs are not rendered by default.

51 changes: 0 additions & 51 deletions drivers/gpu/drm/hisilicon/hisi_ade.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,6 @@
#ifndef __HISI_DRM_ADE_H__
#define __HISI_DRM_ADE_H__

struct hisi_plane {
struct drm_plane base;
void *ctx;
u8 ch;
};

struct hisi_crtc {
struct drm_crtc base;
void *ctx;
struct drm_display_mode *dmode;
bool enable;
u32 ch_mask;
u64 use_mask;
};

void hisi_crtc_atomic_flush(struct drm_crtc *c);
void hisi_crtc_atomic_begin(struct drm_crtc *c);
void hisi_drm_crtc_mode_set_nofb(struct drm_crtc *c);
bool hisi_drm_crtc_mode_fixup(struct drm_crtc *c,
const struct drm_display_mode *mode,
struct drm_display_mode *adj_mode);
void hisi_drm_crtc_mode_prepare(struct drm_crtc *c);
void hisi_crtc_disable(struct drm_crtc *c);
void hisi_crtc_enable(struct drm_crtc *c);
void hisi_drm_crtc_destroy(struct drm_crtc *c);
struct hisi_crtc *hisi_drm_crtc_create(struct drm_device *dev,
void *ctx,
struct drm_plane *p);

void hisi_plane_atomic_disable(struct drm_plane *p,
struct drm_plane_state *old_state);
void hisi_plane_atomic_update(struct drm_plane *p,
struct drm_plane_state *old_state);
int hisi_plane_atomic_check(struct drm_plane *p,
struct drm_plane_state *state);
void hisi_plane_cleanup_fb(struct drm_plane *p,
struct drm_framebuffer *fb,
const struct drm_plane_state *old_state);
void hisi_plane_cleanup_fb(struct drm_plane *p,
struct drm_framebuffer *fb,
const struct drm_plane_state *old_state);
int hisi_plane_prepare_fb(struct drm_plane *p,
struct drm_framebuffer *fb,
const struct drm_plane_state *new_state);
void hisi_plane_destroy(struct drm_plane *p);
int ade_install_plane_properties(struct drm_device *dev,
struct hisi_plane *plane);

extern int hisi_drm_ade_init(void);
extern void hisi_drm_ade_exit(void);

extern int hisi_drm_enable_vblank(struct drm_device *dev, int crtc);
extern void hisi_drm_disable_vblank(struct drm_device *dev, int crtc);

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/hisilicon/hisi_ade_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
*
*/

#ifndef __HISI_ADE_H__
#define __HISI_ADE_H__
#ifndef __HISI_ADE_REG_H__
#define __HISI_ADE_REG_H__

/********** ADE Register Offset ***********/
#define ADE_CTRL (0x4)
Expand Down
40 changes: 22 additions & 18 deletions drivers/gpu/drm/hisilicon/hisi_drm_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,33 @@

#include <linux/io.h>
#include <linux/types.h>
#include <video/videomode.h>

#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <video/videomode.h>
#include <drm/drm_encoder_slave.h>
#include <drm/drm_atomic_helper.h>

#include "hisi_drm_encoder.h"
#include "hisi_drm_drv.h"
#include "hisi_drm_encoder.h"
#include "hisi_drm_connector.h"

#define get_hisi_connector(connector) \
#define to_hisi_connector(connector) \
container_of(connector, struct hisi_connector, connector)

int hisi_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct hisi_connector *hisi_connector = get_hisi_connector(connector);
struct drm_encoder *encoder = hisi_connector->encoder;
struct hisi_connector *hconnector = to_hisi_connector(connector);
struct drm_encoder *encoder = hconnector->encoder;
struct hisi_connector_funcs *ops = hconnector->ops;
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
int ret = MODE_OK;

DRM_DEBUG_DRIVER("enter.\n");

if (hisi_connector->ops->modes_valid)
hisi_connector->ops->modes_valid(connector);
if (ops->modes_valid)
ops->modes_valid(connector);

if (sfuncs && sfuncs->mode_valid) {
ret = sfuncs->mode_valid(encoder, mode);
Expand All @@ -50,8 +53,8 @@ int hisi_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_encoder *
hisi_drm_best_encoder(struct drm_connector *connector)
{
struct hisi_connector *hisi_connector = get_hisi_connector(connector);
struct drm_encoder *encoder = hisi_connector->encoder;
struct hisi_connector *hconnector = to_hisi_connector(connector);
struct drm_encoder *encoder = hconnector->encoder;

DRM_DEBUG_DRIVER("enter.\n");
DRM_DEBUG_DRIVER("exit success.\n");
Expand All @@ -61,9 +64,8 @@ hisi_drm_best_encoder(struct drm_connector *connector)

int hisi_drm_get_modes(struct drm_connector *connector)
{
struct hisi_connector *hisi_connector = get_hisi_connector(connector);
struct drm_encoder *encoder = hisi_connector->encoder;
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
struct hisi_connector *hconnector = to_hisi_connector(connector);
struct hisi_connector_funcs *ops = hconnector->ops;
int count = 0;

DRM_DEBUG_DRIVER("enter.\n");
Expand All @@ -72,8 +74,8 @@ int hisi_drm_get_modes(struct drm_connector *connector)
if (sfuncs && sfuncs->get_modes)
count = sfuncs->get_modes(encoder, connector);
#else
if (hisi_connector->ops->get_modes)
count += hisi_connector->ops->get_modes(connector);
if (ops->get_modes)
count += ops->get_modes(connector);
#endif


Expand All @@ -97,22 +99,24 @@ void hisi_drm_connector_destroy(struct drm_connector *connector)
enum drm_connector_status
hisi_drm_detect(struct drm_connector *connector, bool force)
{
struct hisi_connector *hisi_connector = get_hisi_connector(connector);
struct drm_encoder *encoder = hisi_connector->encoder;
struct hisi_connector *hconnector = to_hisi_connector(connector);
struct drm_encoder *encoder = hconnector->encoder;
struct hisi_connector_funcs *ops = hconnector->ops;
struct drm_encoder_slave_funcs *sfuncs = get_slave_funcs(encoder);
enum drm_connector_status status = connector_status_unknown;

DRM_DEBUG_DRIVER("enter.\n");

if (hisi_connector->ops->detect)
hisi_connector->ops->detect(connector);
if (ops->detect)
ops->detect(connector);

if (sfuncs && sfuncs->detect)
status = sfuncs->detect(encoder, connector);

DRM_DEBUG_DRIVER("exit success. status=%d\n", status);
return status;
}

static struct drm_connector_funcs hisi_drm_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
Expand Down
13 changes: 13 additions & 0 deletions drivers/gpu/drm/hisilicon/hisi_drm_connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
#ifndef __HISI_DRM_CONNECTOR_H__
#define __HISI_DRM_CONNECTOR_H__

struct hisi_connector_funcs {
enum drm_connector_status (*detect)
(struct drm_connector *connector);
int (*get_modes)(struct drm_connector *connector);
int (*modes_valid)(struct drm_connector *connector);
};

struct hisi_connector {
struct drm_connector connector;
struct drm_encoder *encoder;
void *ops;
};

void hisi_drm_connector_init(struct drm_device *dev, struct drm_encoder *encoder,
struct drm_connector *connector);

Expand Down
124 changes: 104 additions & 20 deletions drivers/gpu/drm/hisilicon/hisi_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,112 @@
*/

#include <drm/drmP.h>

#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_encoder_slave.h>
#include <drm/drm_atomic_helper.h>

#include "hisi_drm_drv.h"
#include "hisi_drm_plane.h"
#include "hisi_drm_crtc.h"
#include "hisi_ade.h"

#define to_hisi_crtc(c) container_of(c, struct hisi_crtc, base)

static void hisi_drm_crtc_enable(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (hcrtc->enable)
return;

if (ops->enable)
ops->enable(hcrtc);
drm_crtc_vblank_on(crtc);

hcrtc->enable = true;
}

static void hisi_drm_crtc_disable(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (!hcrtc->enable)
return;

drm_crtc_vblank_off(crtc);
if (ops->disable)
ops->disable(hcrtc);

hcrtc->enable = false;
}

static void hisi_drm_crtc_mode_prepare(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (ops->mode_prepare)
ops->mode_prepare(hcrtc);
}

static bool hisi_drm_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;
bool ret = true;

if (ops->mode_fixup)
ret = ops->mode_fixup(hcrtc, mode, adj_mode);

return ret;
}

static void hisi_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (ops->mode_set_nofb)
ops->mode_set_nofb(hcrtc);
}

static void hisi_crtc_atomic_begin(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (ops->atomic_begin)
ops->atomic_begin(hcrtc);
}

static void hisi_crtc_atomic_flush(struct drm_crtc *crtc)
{
struct hisi_crtc *hcrtc = to_hisi_crtc(crtc);
struct hisi_crtc_ops *ops = hcrtc->ops;

if (ops->atomic_flush)
ops->atomic_flush(hcrtc);
}

static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
.enable = hisi_crtc_enable,
.disable = hisi_crtc_disable,
.enable = hisi_drm_crtc_enable,
.disable = hisi_drm_crtc_disable,
.prepare = hisi_drm_crtc_mode_prepare,
.mode_fixup = hisi_drm_crtc_mode_fixup,
.mode_set_nofb = hisi_drm_crtc_mode_set_nofb,
.atomic_begin = hisi_crtc_atomic_begin,
.atomic_flush = hisi_crtc_atomic_flush,
};

static void hisi_drm_crtc_destroy(struct drm_crtc *c)
{
drm_crtc_cleanup(c);
}

static const struct drm_crtc_funcs crtc_funcs = {
.destroy = hisi_drm_crtc_destroy,
.set_config = drm_atomic_helper_set_config,
Expand All @@ -39,26 +126,23 @@ static const struct drm_crtc_funcs crtc_funcs = {
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
};

struct hisi_crtc *hisi_drm_crtc_create(struct drm_device *dev,
void *ctx,
struct drm_plane *p)
int hisi_drm_crtc_init(struct drm_device *dev,
struct hisi_crtc *hcrtc,
struct drm_plane *plane)
{
struct hisi_crtc *crtc;
struct hisi_drm_private *private = dev->dev_private;
struct hisi_drm_private *priv = dev->dev_private;
int ret;

crtc = devm_kzalloc(dev->dev, sizeof(*crtc), GFP_KERNEL);
if (!crtc)
return ERR_PTR(-ENOMEM);

ret = drm_crtc_init_with_planes(dev, &crtc->base, p,
ret = drm_crtc_init_with_planes(dev, &hcrtc->base, plane,
NULL, &crtc_funcs);
if (ret)
return ERR_PTR(ret);
if (ret) {
DRM_ERROR("failed to init crtc.\n");
return ret;
}

drm_crtc_helper_add(&crtc->base, &crtc_helper_funcs);
drm_crtc_helper_add(&hcrtc->base, &crtc_helper_funcs);

private->crtc = &crtc->base;
crtc->ctx = ctx;
return crtc;
priv->crtc = &hcrtc->base;

return 0;
}
25 changes: 22 additions & 3 deletions drivers/gpu/drm/hisilicon/hisi_drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,28 @@

#ifndef __HISI_DRM_CRTC_H__
#define __HISI_DRM_CRTC_H__
#include "hisi_handle.h"

struct hisi_crtc *hisi_drm_crtc_init (struct drm_device *drm_dev,
struct hisi_handle *hisi_handle, struct drm_plane *p);
struct hisi_crtc {
struct drm_crtc base;
void *ops;
bool enable;
};

struct hisi_crtc_ops {
void (*disable)(struct hisi_crtc *hcrtc);
void (*enable)(struct hisi_crtc *hcrtc);
void (*mode_prepare)(struct hisi_crtc *hcrtc);
bool (*mode_fixup)(struct hisi_crtc *hcrtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adj_mode);
void (*mode_set_nofb)(struct hisi_crtc *hcrtc);
void (*atomic_begin)(struct hisi_crtc *hcrtc);
void (*atomic_flush)(struct hisi_crtc *hcrtc);
void (*destroy)(struct hisi_crtc *hcrtc);
};

extern int hisi_drm_crtc_init(struct drm_device *dev,
struct hisi_crtc *crtc,
struct drm_plane *plane);

#endif
Loading