mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
Merge tag 'drm-misc-next-2017-08-08' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes: - vc4: Add ioctl to allow attaching a label to a bo (Eric) - Add new format/modifier blob plane property (Ben) - armada: Use __u32/__u64 instead of uint32_t/uint64_t (Mikko) - [kinda uapi] fb_helper: Expose display_info size via fb_info (David) Core Changes: - Default gem_dumb_[map_offset|destroy] as mmap/destroy implementations (Noralf) - Simplify atomic properties by removing the helpers and handling in core (Daniel) Driver Changes: - stm: Add STM32 DSI controller driver (Phillipe) - vc4: Add HDMI CEC support (Hans) - rockchip: Refactor register init & soc version handling (Mark) - misc: Remove .load_lut, .gamma_set, .gamma_get dead code (Peter) - dw-hdmi: Add HDMI CEC support (Russell) Cc: Philippe CORNU <philippe.cornu@st.com> Cc: Hans Verkuil <hans.verkuil@cisco.com> Cc: Eric Anholt <eric@anholt.net> Cc: Noralf Trønnes <noralf@tronnes.org> Cc: Ben Widawsky <ben@bwidawsk.net> Cc: Mark yao <mark.yao@rock-chips.com> Cc: Peter Rosin <peda@axentia.se> Cc: Russell King <rmk+kernel@armlinux.org.uk> Cc: Mikko Rapeli <mikko.rapeli@iki.fi> Cc: David Lechner <david@lechnology.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> * tag 'drm-misc-next-2017-08-08' of git://anongit.freedesktop.org/git/drm-misc: (107 commits) drm: Nuke drm_atomic_legacy_backoff drm: Nuke drm_atomic_helper_connector_dpms drm: Nuke drm_atomic_helper_connector_set_property drm: Nuke drm_atomic_helper_plane_set_property drm: Nuke drm_atomic_helper_crtc_set_property drm: Handle properties in the core for atomic drivers drm: Don't update property values for atomic drivers drm/omap: Rework the rotation-on-crtc hack drm/radeon: Use the drm_driver.dumb_destroy default drm/i915: Use the drm_driver.dumb_destroy default drm/sti: Use .dumb_map_offset and .dumb_destroy defaults drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY drm/fb-helper: pass physical dimensions to fbdev uapi drm/armada_drm.h: use __u32 and __u64 instead of uint32_t and uint64_t drm/bridge: dw-hdmi: remove CEC engine register definitions drm/bridge: dw-hdmi: add cec driver drm/bridge: dw-hdmi: add missing cec_notifier_put drm: remove unused and redundant callbacks staging: vboxvideo: remove dead gamma lut code drm: dw-hdmi-i2s: add missing company name on Copyright ...
This commit is contained in:
commit
09ef2378dc
@ -8,8 +8,12 @@ Required properties:
|
||||
- compatible: value should be one of the following
|
||||
"rockchip,rk3036-vop";
|
||||
"rockchip,rk3288-vop";
|
||||
"rockchip,rk3368-vop";
|
||||
"rockchip,rk3366-vop";
|
||||
"rockchip,rk3399-vop-big";
|
||||
"rockchip,rk3399-vop-lit";
|
||||
"rockchip,rk3228-vop";
|
||||
"rockchip,rk3328-vop";
|
||||
|
||||
- interrupts: should contain a list of all VOP IP block interrupts in the
|
||||
order: VSYNC, LCD_SYSTEM. The interrupt specifier
|
||||
|
@ -1,7 +1,6 @@
|
||||
* STMicroelectronics STM32 lcd-tft display controller
|
||||
|
||||
- ltdc: lcd-tft display controller host
|
||||
must be a sub-node of st-display-subsystem
|
||||
Required properties:
|
||||
- compatible: "st,stm32-ltdc"
|
||||
- reg: Physical base address of the IP registers and length of memory mapped region.
|
||||
@ -13,8 +12,40 @@
|
||||
Required nodes:
|
||||
- Video port for RGB output.
|
||||
|
||||
Example:
|
||||
* STMicroelectronics STM32 DSI controller specific extensions to Synopsys
|
||||
DesignWare MIPI DSI host controller
|
||||
|
||||
The STMicroelectronics STM32 DSI controller uses the Synopsys DesignWare MIPI
|
||||
DSI host controller. For all mandatory properties & nodes, please refer
|
||||
to the related documentation in [5].
|
||||
|
||||
Mandatory properties specific to STM32 DSI:
|
||||
- #address-cells: Should be <1>.
|
||||
- #size-cells: Should be <0>.
|
||||
- compatible: "st,stm32-dsi".
|
||||
- clock-names:
|
||||
- phy pll reference clock string name, must be "ref".
|
||||
- resets: see [5].
|
||||
- reset-names: see [5].
|
||||
|
||||
Mandatory nodes specific to STM32 DSI:
|
||||
- ports: A node containing DSI input & output port nodes with endpoint
|
||||
definitions as documented in [3] & [4].
|
||||
- port@0: DSI input port node, connected to the ltdc rgb output port.
|
||||
- port@1: DSI output port node, connected to a panel or a bridge input port.
|
||||
- panel or bridge node: A node containing the panel or bridge description as
|
||||
documented in [6].
|
||||
- port: panel or bridge port node, connected to the DSI output port (port@1).
|
||||
|
||||
Note: You can find more documentation in the following references
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
[2] Documentation/devicetree/bindings/reset/reset.txt
|
||||
[3] Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
[4] Documentation/devicetree/bindings/graph.txt
|
||||
[5] Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt
|
||||
[6] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
|
||||
|
||||
Example 1: RGB panel
|
||||
/ {
|
||||
...
|
||||
soc {
|
||||
@ -34,3 +65,73 @@ Example:
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Example 2: DSI panel
|
||||
|
||||
/ {
|
||||
...
|
||||
soc {
|
||||
...
|
||||
ltdc: display-controller@40016800 {
|
||||
compatible = "st,stm32-ltdc";
|
||||
reg = <0x40016800 0x200>;
|
||||
interrupts = <88>, <89>;
|
||||
resets = <&rcc STM32F4_APB2_RESET(LTDC)>;
|
||||
clocks = <&rcc 1 CLK_LCD>;
|
||||
clock-names = "lcd";
|
||||
|
||||
port {
|
||||
ltdc_out_dsi: endpoint {
|
||||
remote-endpoint = <&dsi_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
dsi: dsi@40016c00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "st,stm32-dsi";
|
||||
reg = <0x40016c00 0x800>;
|
||||
clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>;
|
||||
clock-names = "ref", "pclk";
|
||||
resets = <&rcc STM32F4_APB2_RESET(DSI)>;
|
||||
reset-names = "apb";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi_in: endpoint {
|
||||
remote-endpoint = <<dc_out_dsi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi_out: endpoint {
|
||||
remote-endpoint = <&dsi_in_panel>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
panel-dsi@0 {
|
||||
reg = <0>; /* dsi virtual channel (0..3) */
|
||||
compatible = ...;
|
||||
enable-gpios = ...;
|
||||
|
||||
port {
|
||||
dsi_in_panel: endpoint {
|
||||
remote-endpoint = <&dsi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
@ -108,8 +108,8 @@ This would be especially useful for tinydrm:
|
||||
crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
|
||||
__drm_atomic_helper_crtc_duplicate_state().
|
||||
|
||||
- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_
|
||||
prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this
|
||||
- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm\_
|
||||
prefix ofc and using drm_fb\_. drm_framebuffer.c makes sense since this
|
||||
is a function useful to implement the fb->dirty function.
|
||||
|
||||
- Create a new drm_fb_dirty function which does essentially what e.g.
|
||||
|
@ -125,97 +125,6 @@ static void sync_timeline_put(struct sync_timeline *obj)
|
||||
kref_put(&obj->kref, sync_timeline_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_timeline_signal() - signal a status change on a sync_timeline
|
||||
* @obj: sync_timeline to signal
|
||||
* @inc: num to increment on timeline->value
|
||||
*
|
||||
* A sync implementation should call this any time one of it's fences
|
||||
* has signaled or has an error condition.
|
||||
*/
|
||||
static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
|
||||
{
|
||||
struct sync_pt *pt, *next;
|
||||
|
||||
trace_sync_timeline(obj);
|
||||
|
||||
spin_lock_irq(&obj->lock);
|
||||
|
||||
obj->value += inc;
|
||||
|
||||
list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
|
||||
if (!dma_fence_is_signaled_locked(&pt->base))
|
||||
break;
|
||||
|
||||
list_del_init(&pt->link);
|
||||
rb_erase(&pt->node, &obj->pt_tree);
|
||||
}
|
||||
|
||||
spin_unlock_irq(&obj->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_pt_create() - creates a sync pt
|
||||
* @parent: fence's parent sync_timeline
|
||||
* @inc: value of the fence
|
||||
*
|
||||
* Creates a new sync_pt as a child of @parent. @size bytes will be
|
||||
* allocated allowing for implementation specific data to be kept after
|
||||
* the generic sync_timeline struct. Returns the sync_pt object or
|
||||
* NULL in case of error.
|
||||
*/
|
||||
static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
|
||||
unsigned int value)
|
||||
{
|
||||
struct sync_pt *pt;
|
||||
|
||||
pt = kzalloc(sizeof(*pt), GFP_KERNEL);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
|
||||
sync_timeline_get(obj);
|
||||
dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
|
||||
obj->context, value);
|
||||
INIT_LIST_HEAD(&pt->link);
|
||||
|
||||
spin_lock_irq(&obj->lock);
|
||||
if (!dma_fence_is_signaled_locked(&pt->base)) {
|
||||
struct rb_node **p = &obj->pt_tree.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
|
||||
while (*p) {
|
||||
struct sync_pt *other;
|
||||
int cmp;
|
||||
|
||||
parent = *p;
|
||||
other = rb_entry(parent, typeof(*pt), node);
|
||||
cmp = value - other->base.seqno;
|
||||
if (cmp > 0) {
|
||||
p = &parent->rb_right;
|
||||
} else if (cmp < 0) {
|
||||
p = &parent->rb_left;
|
||||
} else {
|
||||
if (dma_fence_get_rcu(&other->base)) {
|
||||
dma_fence_put(&pt->base);
|
||||
pt = other;
|
||||
goto unlock;
|
||||
}
|
||||
p = &parent->rb_left;
|
||||
}
|
||||
}
|
||||
rb_link_node(&pt->node, parent, p);
|
||||
rb_insert_color(&pt->node, &obj->pt_tree);
|
||||
|
||||
parent = rb_next(&pt->node);
|
||||
list_add_tail(&pt->link,
|
||||
parent ? &rb_entry(parent, typeof(*pt), node)->link : &obj->pt_list);
|
||||
}
|
||||
unlock:
|
||||
spin_unlock_irq(&obj->lock);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
|
||||
{
|
||||
return "sw_sync";
|
||||
@ -285,6 +194,107 @@ static const struct dma_fence_ops timeline_fence_ops = {
|
||||
.timeline_value_str = timeline_fence_timeline_value_str,
|
||||
};
|
||||
|
||||
/**
|
||||
* sync_timeline_signal() - signal a status change on a sync_timeline
|
||||
* @obj: sync_timeline to signal
|
||||
* @inc: num to increment on timeline->value
|
||||
*
|
||||
* A sync implementation should call this any time one of it's fences
|
||||
* has signaled or has an error condition.
|
||||
*/
|
||||
static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
|
||||
{
|
||||
struct sync_pt *pt, *next;
|
||||
|
||||
trace_sync_timeline(obj);
|
||||
|
||||
spin_lock_irq(&obj->lock);
|
||||
|
||||
obj->value += inc;
|
||||
|
||||
list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
|
||||
if (!timeline_fence_signaled(&pt->base))
|
||||
break;
|
||||
|
||||
list_del_init(&pt->link);
|
||||
rb_erase(&pt->node, &obj->pt_tree);
|
||||
|
||||
/*
|
||||
* A signal callback may release the last reference to this
|
||||
* fence, causing it to be freed. That operation has to be
|
||||
* last to avoid a use after free inside this loop, and must
|
||||
* be after we remove the fence from the timeline in order to
|
||||
* prevent deadlocking on timeline->lock inside
|
||||
* timeline_fence_release().
|
||||
*/
|
||||
dma_fence_signal_locked(&pt->base);
|
||||
}
|
||||
|
||||
spin_unlock_irq(&obj->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_pt_create() - creates a sync pt
|
||||
* @parent: fence's parent sync_timeline
|
||||
* @inc: value of the fence
|
||||
*
|
||||
* Creates a new sync_pt as a child of @parent. @size bytes will be
|
||||
* allocated allowing for implementation specific data to be kept after
|
||||
* the generic sync_timeline struct. Returns the sync_pt object or
|
||||
* NULL in case of error.
|
||||
*/
|
||||
static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
|
||||
unsigned int value)
|
||||
{
|
||||
struct sync_pt *pt;
|
||||
|
||||
pt = kzalloc(sizeof(*pt), GFP_KERNEL);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
|
||||
sync_timeline_get(obj);
|
||||
dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
|
||||
obj->context, value);
|
||||
INIT_LIST_HEAD(&pt->link);
|
||||
|
||||
spin_lock_irq(&obj->lock);
|
||||
if (!dma_fence_is_signaled_locked(&pt->base)) {
|
||||
struct rb_node **p = &obj->pt_tree.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
|
||||
while (*p) {
|
||||
struct sync_pt *other;
|
||||
int cmp;
|
||||
|
||||
parent = *p;
|
||||
other = rb_entry(parent, typeof(*pt), node);
|
||||
cmp = value - other->base.seqno;
|
||||
if (cmp > 0) {
|
||||
p = &parent->rb_right;
|
||||
} else if (cmp < 0) {
|
||||
p = &parent->rb_left;
|
||||
} else {
|
||||
if (dma_fence_get_rcu(&other->base)) {
|
||||
dma_fence_put(&pt->base);
|
||||
pt = other;
|
||||
goto unlock;
|
||||
}
|
||||
p = &parent->rb_left;
|
||||
}
|
||||
}
|
||||
rb_link_node(&pt->node, parent, p);
|
||||
rb_insert_color(&pt->node, &obj->pt_tree);
|
||||
|
||||
parent = rb_next(&pt->node);
|
||||
list_add_tail(&pt->link,
|
||||
parent ? &rb_entry(parent, typeof(*pt), node)->link : &obj->pt_list);
|
||||
}
|
||||
unlock:
|
||||
spin_unlock_irq(&obj->lock);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
/*
|
||||
* *WARNING*
|
||||
*
|
||||
|
@ -304,7 +304,7 @@ static int sync_file_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct sync_file *sync_file = file->private_data;
|
||||
|
||||
if (test_bit(POLL_ENABLED, &sync_file->fence->flags))
|
||||
if (test_bit(POLL_ENABLED, &sync_file->flags))
|
||||
dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
|
||||
dma_fence_put(sync_file->fence);
|
||||
kfree(sync_file);
|
||||
@ -318,7 +318,8 @@ static unsigned int sync_file_poll(struct file *file, poll_table *wait)
|
||||
|
||||
poll_wait(file, &sync_file->wq, wait);
|
||||
|
||||
if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
|
||||
if (list_empty(&sync_file->cb.node) &&
|
||||
!test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
|
||||
if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
|
||||
fence_check_cb_func) < 0)
|
||||
wake_up_all(&sync_file->wq);
|
||||
|
@ -834,7 +834,6 @@ static struct drm_driver kms_driver = {
|
||||
.gem_close_object = amdgpu_gem_object_close,
|
||||
.dumb_create = amdgpu_mode_dumb_create,
|
||||
.dumb_map_offset = amdgpu_mode_dumb_mmap,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.fops = &amdgpu_driver_kms_fops,
|
||||
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
|
@ -311,31 +311,7 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Sets the color ramps on behalf of fbcon */
|
||||
static void amdgpu_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
amdgpu_crtc->lut_r[regno] = red >> 6;
|
||||
amdgpu_crtc->lut_g[regno] = green >> 6;
|
||||
amdgpu_crtc->lut_b[regno] = blue >> 6;
|
||||
}
|
||||
|
||||
/** Gets the color ramps on behalf of fbcon */
|
||||
static void amdgpu_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, int regno)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
*red = amdgpu_crtc->lut_r[regno] << 6;
|
||||
*green = amdgpu_crtc->lut_g[regno] << 6;
|
||||
*blue = amdgpu_crtc->lut_b[regno] << 6;
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
|
||||
.gamma_set = amdgpu_crtc_fb_gamma_set,
|
||||
.gamma_get = amdgpu_crtc_fb_gamma_get,
|
||||
.fb_probe = amdgpufb_create,
|
||||
};
|
||||
|
||||
|
@ -357,7 +357,6 @@ struct amdgpu_atom_ss {
|
||||
struct amdgpu_crtc {
|
||||
struct drm_crtc base;
|
||||
int crtc_id;
|
||||
u16 lut_r[256], lut_g[256], lut_b[256];
|
||||
bool enabled;
|
||||
bool can_tile;
|
||||
uint32_t crtc_offset;
|
||||
|
@ -2139,6 +2139,7 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
u32 tmp;
|
||||
|
||||
@ -2176,11 +2177,14 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
|
||||
|
||||
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
for (i = 0; i < 256; i++) {
|
||||
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
|
||||
(amdgpu_crtc->lut_r[i] << 20) |
|
||||
(amdgpu_crtc->lut_g[i] << 10) |
|
||||
(amdgpu_crtc->lut_b[i] << 0));
|
||||
((*r++ & 0xffc0) << 14) |
|
||||
((*g++ & 0xffc0) << 4) |
|
||||
(*b++ >> 6));
|
||||
}
|
||||
|
||||
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
@ -2496,15 +2500,6 @@ static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v10_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
@ -2716,14 +2711,12 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
|
||||
.mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic,
|
||||
.prepare = dce_v10_0_crtc_prepare,
|
||||
.commit = dce_v10_0_crtc_commit,
|
||||
.load_lut = dce_v10_0_crtc_load_lut,
|
||||
.disable = dce_v10_0_crtc_disable,
|
||||
};
|
||||
|
||||
static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
int i;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
@ -2741,12 +2734,6 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
|
||||
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
amdgpu_crtc->lut_r[i] = i << 2;
|
||||
amdgpu_crtc->lut_g[i] = i << 2;
|
||||
amdgpu_crtc->lut_b[i] = i << 2;
|
||||
}
|
||||
|
||||
switch (amdgpu_crtc->crtc_id) {
|
||||
case 0:
|
||||
default:
|
||||
|
@ -2178,6 +2178,7 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
u32 tmp;
|
||||
|
||||
@ -2209,11 +2210,14 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
|
||||
|
||||
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
for (i = 0; i < 256; i++) {
|
||||
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
|
||||
(amdgpu_crtc->lut_r[i] << 20) |
|
||||
(amdgpu_crtc->lut_g[i] << 10) |
|
||||
(amdgpu_crtc->lut_b[i] << 0));
|
||||
((*r++ & 0xffc0) << 14) |
|
||||
((*g++ & 0xffc0) << 4) |
|
||||
(*b++ >> 6));
|
||||
}
|
||||
|
||||
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
@ -2571,15 +2575,6 @@ static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v11_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
@ -2819,14 +2814,12 @@ static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
|
||||
.mode_set_base_atomic = dce_v11_0_crtc_set_base_atomic,
|
||||
.prepare = dce_v11_0_crtc_prepare,
|
||||
.commit = dce_v11_0_crtc_commit,
|
||||
.load_lut = dce_v11_0_crtc_load_lut,
|
||||
.disable = dce_v11_0_crtc_disable,
|
||||
};
|
||||
|
||||
static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
int i;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
@ -2844,12 +2837,6 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
|
||||
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
amdgpu_crtc->lut_r[i] = i << 2;
|
||||
amdgpu_crtc->lut_g[i] = i << 2;
|
||||
amdgpu_crtc->lut_b[i] = i << 2;
|
||||
}
|
||||
|
||||
switch (amdgpu_crtc->crtc_id) {
|
||||
case 0:
|
||||
default:
|
||||
|
@ -2071,6 +2071,7 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
|
||||
@ -2100,11 +2101,14 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
|
||||
|
||||
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
for (i = 0; i < 256; i++) {
|
||||
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
|
||||
(amdgpu_crtc->lut_r[i] << 20) |
|
||||
(amdgpu_crtc->lut_g[i] << 10) |
|
||||
(amdgpu_crtc->lut_b[i] << 0));
|
||||
((*r++ & 0xffc0) << 14) |
|
||||
((*g++ & 0xffc0) << 4) |
|
||||
(*b++ >> 6));
|
||||
}
|
||||
|
||||
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
@ -2385,15 +2389,6 @@ static int dce_v6_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v6_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
@ -2601,14 +2596,12 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
|
||||
.mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic,
|
||||
.prepare = dce_v6_0_crtc_prepare,
|
||||
.commit = dce_v6_0_crtc_commit,
|
||||
.load_lut = dce_v6_0_crtc_load_lut,
|
||||
.disable = dce_v6_0_crtc_disable,
|
||||
};
|
||||
|
||||
static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
int i;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
@ -2626,12 +2619,6 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
|
||||
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
amdgpu_crtc->lut_r[i] = i << 2;
|
||||
amdgpu_crtc->lut_g[i] = i << 2;
|
||||
amdgpu_crtc->lut_b[i] = i << 2;
|
||||
}
|
||||
|
||||
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
|
||||
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
|
@ -2049,6 +2049,7 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
|
||||
@ -2078,11 +2079,14 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
|
||||
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
|
||||
|
||||
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
for (i = 0; i < 256; i++) {
|
||||
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
|
||||
(amdgpu_crtc->lut_r[i] << 20) |
|
||||
(amdgpu_crtc->lut_g[i] << 10) |
|
||||
(amdgpu_crtc->lut_b[i] << 0));
|
||||
((*r++ & 0xffc0) << 14) |
|
||||
((*g++ & 0xffc0) << 4) |
|
||||
(*b++ >> 6));
|
||||
}
|
||||
|
||||
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
@ -2400,15 +2404,6 @@ static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v8_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
@ -2627,14 +2622,12 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
|
||||
.mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic,
|
||||
.prepare = dce_v8_0_crtc_prepare,
|
||||
.commit = dce_v8_0_crtc_commit,
|
||||
.load_lut = dce_v8_0_crtc_load_lut,
|
||||
.disable = dce_v8_0_crtc_disable,
|
||||
};
|
||||
|
||||
static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
int i;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
@ -2652,12 +2645,6 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
|
||||
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
|
||||
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
amdgpu_crtc->lut_r[i] = i << 2;
|
||||
amdgpu_crtc->lut_g[i] = i << 2;
|
||||
amdgpu_crtc->lut_b[i] = i << 2;
|
||||
}
|
||||
|
||||
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
|
||||
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
|
@ -112,16 +112,6 @@ static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
|
||||
u16 *green, u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -233,11 +223,6 @@ static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
@ -253,14 +238,12 @@ static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
|
||||
.mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
|
||||
.prepare = dce_virtual_crtc_prepare,
|
||||
.commit = dce_virtual_crtc_commit,
|
||||
.load_lut = dce_virtual_crtc_load_lut,
|
||||
.disable = dce_virtual_crtc_disable,
|
||||
};
|
||||
|
||||
static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
int i;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
@ -273,12 +256,6 @@ static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
|
||||
amdgpu_crtc->crtc_id = index;
|
||||
adev->mode_info.crtcs[index] = amdgpu_crtc;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
amdgpu_crtc->lut_r[i] = i << 2;
|
||||
amdgpu_crtc->lut_g[i] = i << 2;
|
||||
amdgpu_crtc->lut_b[i] = i << 2;
|
||||
}
|
||||
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
amdgpu_crtc->encoder = NULL;
|
||||
amdgpu_crtc->connector = NULL;
|
||||
|
@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm)
|
||||
|
||||
ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs,
|
||||
formats, ARRAY_SIZE(formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
@ -176,8 +176,6 @@ static struct drm_driver arcpgu_drm_driver = {
|
||||
.patchlevel = 0,
|
||||
.fops = &arcpgu_drm_ops,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
|
@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
|
||||
|
||||
ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
|
||||
formats, ARRAY_SIZE(formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
return ERR_PTR(ret);
|
||||
|
@ -253,8 +253,6 @@ static struct drm_driver hdlcd_driver = {
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_export = drm_gem_prime_export,
|
||||
|
@ -331,8 +331,6 @@ static struct drm_driver malidp_driver = {
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_export = drm_gem_prime_export,
|
||||
|
@ -128,7 +128,6 @@ static void malidp_plane_atomic_print_state(struct drm_printer *p,
|
||||
static const struct drm_plane_funcs malidp_de_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.destroy = malidp_de_plane_destroy,
|
||||
.reset = malidp_plane_reset,
|
||||
.atomic_duplicate_state = malidp_duplicate_plane_state,
|
||||
@ -398,7 +397,7 @@ int malidp_de_planes_init(struct drm_device *drm)
|
||||
DRM_PLANE_TYPE_OVERLAY;
|
||||
ret = drm_universal_plane_init(drm, &plane->base, crtcs,
|
||||
&malidp_de_plane_funcs, formats,
|
||||
n, plane_type, NULL);
|
||||
n, NULL, plane_type, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -334,16 +334,6 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
|
||||
armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
|
||||
}
|
||||
|
||||
void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
|
||||
int idx)
|
||||
{
|
||||
}
|
||||
|
||||
void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
int idx)
|
||||
{
|
||||
}
|
||||
|
||||
/* The mode_config.mutex will be held for this call */
|
||||
static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
|
||||
{
|
||||
@ -1269,6 +1259,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
|
||||
&armada_primary_plane_funcs,
|
||||
armada_primary_formats,
|
||||
ARRAY_SIZE(armada_primary_formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
|
@ -102,8 +102,6 @@ struct armada_crtc {
|
||||
};
|
||||
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
|
||||
|
||||
void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
|
||||
void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
|
||||
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
|
||||
|
||||
void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
|
||||
|
@ -117,8 +117,6 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
|
||||
.gamma_set = armada_drm_crtc_gamma_set,
|
||||
.gamma_get = armada_drm_crtc_gamma_get,
|
||||
.fb_probe = armada_fb_probe,
|
||||
};
|
||||
|
||||
|
@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
|
||||
&armada_ovl_plane_funcs,
|
||||
armada_ovl_formats,
|
||||
ARRAY_SIZE(armada_ovl_formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
if (ret) {
|
||||
kfree(dplane);
|
||||
|
@ -245,7 +245,6 @@ struct ast_connector {
|
||||
|
||||
struct ast_crtc {
|
||||
struct drm_crtc base;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
struct drm_gem_object *cursor_bo;
|
||||
uint64_t cursor_addr;
|
||||
int cursor_width, cursor_height;
|
||||
|
@ -254,27 +254,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ast_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
ast_crtc->lut_r[regno] = red >> 8;
|
||||
ast_crtc->lut_g[regno] = green >> 8;
|
||||
ast_crtc->lut_b[regno] = blue >> 8;
|
||||
}
|
||||
|
||||
static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, int regno)
|
||||
{
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
*red = ast_crtc->lut_r[regno] << 8;
|
||||
*green = ast_crtc->lut_g[regno] << 8;
|
||||
*blue = ast_crtc->lut_b[regno] << 8;
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs ast_fb_helper_funcs = {
|
||||
.gamma_set = ast_fb_gamma_set,
|
||||
.gamma_get = ast_fb_gamma_get,
|
||||
.fb_probe = astfb_create,
|
||||
};
|
||||
|
||||
|
@ -63,15 +63,18 @@ static inline void ast_load_palette_index(struct ast_private *ast,
|
||||
static void ast_crtc_load_lut(struct drm_crtc *crtc)
|
||||
{
|
||||
struct ast_private *ast = crtc->dev->dev_private;
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
|
||||
if (!crtc->enabled)
|
||||
return;
|
||||
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ast_load_palette_index(ast, i, ast_crtc->lut_r[i],
|
||||
ast_crtc->lut_g[i], ast_crtc->lut_b[i]);
|
||||
ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
|
||||
}
|
||||
|
||||
static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
@ -649,7 +652,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
|
||||
.mode_set = ast_crtc_mode_set,
|
||||
.mode_set_base = ast_crtc_mode_set_base,
|
||||
.disable = ast_crtc_disable,
|
||||
.load_lut = ast_crtc_load_lut,
|
||||
.prepare = ast_crtc_prepare,
|
||||
.commit = ast_crtc_commit,
|
||||
|
||||
@ -664,15 +666,6 @@ static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = 0; i < size; i++) {
|
||||
ast_crtc->lut_r[i] = red[i] >> 8;
|
||||
ast_crtc->lut_g[i] = green[i] >> 8;
|
||||
ast_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
ast_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
@ -697,7 +690,6 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {
|
||||
static int ast_crtc_init(struct drm_device *dev)
|
||||
{
|
||||
struct ast_crtc *crtc;
|
||||
int i;
|
||||
|
||||
crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL);
|
||||
if (!crtc)
|
||||
@ -706,12 +698,6 @@ static int ast_crtc_init(struct drm_device *dev)
|
||||
drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&crtc->base, 256);
|
||||
drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
crtc->lut_r[i] = i;
|
||||
crtc->lut_g[i] = i;
|
||||
crtc->lut_b[i] = i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -431,7 +431,6 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
|
||||
.atomic_destroy_state = atmel_hlcdc_crtc_destroy_state,
|
||||
.enable_vblank = atmel_hlcdc_crtc_enable_vblank,
|
||||
.disable_vblank = atmel_hlcdc_crtc_disable_vblank,
|
||||
.set_property = drm_atomic_helper_crtc_set_property,
|
||||
.gamma_set = drm_atomic_helper_legacy_gamma_set,
|
||||
};
|
||||
|
||||
|
@ -761,8 +761,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
|
||||
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
|
||||
.gem_prime_mmap = drm_gem_cma_prime_mmap,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.fops = &fops,
|
||||
.name = "atmel-hlcdc",
|
||||
.desc = "Atmel HLCD Controller DRM",
|
||||
|
@ -838,7 +838,7 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
|
||||
struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
|
||||
|
||||
if (plane->base.fb)
|
||||
drm_framebuffer_unreference(plane->base.fb);
|
||||
drm_framebuffer_put(plane->base.fb);
|
||||
|
||||
drm_plane_cleanup(p);
|
||||
}
|
||||
@ -940,7 +940,7 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
|
||||
desc->name);
|
||||
}
|
||||
|
||||
static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
|
||||
static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
|
||||
.atomic_check = atmel_hlcdc_plane_atomic_check,
|
||||
.atomic_update = atmel_hlcdc_plane_atomic_update,
|
||||
.atomic_disable = atmel_hlcdc_plane_atomic_disable,
|
||||
@ -987,7 +987,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
|
||||
state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state);
|
||||
|
||||
if (state->base.fb)
|
||||
drm_framebuffer_unreference(state->base.fb);
|
||||
drm_framebuffer_put(state->base.fb);
|
||||
|
||||
kfree(state);
|
||||
p->state = NULL;
|
||||
@ -1025,7 +1025,7 @@ atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p)
|
||||
}
|
||||
|
||||
if (copy->base.fb)
|
||||
drm_framebuffer_reference(copy->base.fb);
|
||||
drm_framebuffer_get(copy->base.fb);
|
||||
|
||||
return ©->base;
|
||||
}
|
||||
@ -1044,15 +1044,14 @@ static void atmel_hlcdc_plane_atomic_destroy_state(struct drm_plane *p,
|
||||
}
|
||||
|
||||
if (s->fb)
|
||||
drm_framebuffer_unreference(s->fb);
|
||||
drm_framebuffer_put(s->fb);
|
||||
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static struct drm_plane_funcs layer_plane_funcs = {
|
||||
static const struct drm_plane_funcs layer_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.destroy = atmel_hlcdc_plane_destroy,
|
||||
.reset = atmel_hlcdc_plane_reset,
|
||||
.atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
|
||||
@ -1087,7 +1086,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
|
||||
ret = drm_universal_plane_init(dev, &plane->base, 0,
|
||||
&layer_plane_funcs,
|
||||
desc->formats->formats,
|
||||
desc->formats->nformats, type, NULL);
|
||||
desc->formats->nformats,
|
||||
NULL, type, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -786,7 +786,6 @@ adv7511_connector_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static struct drm_connector_funcs adv7511_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = adv7511_connector_detect,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -1002,7 +1002,6 @@ static enum drm_connector_status anx78xx_detect(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs anx78xx_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = anx78xx_detect,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -1005,7 +1005,6 @@ analogix_dp_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs analogix_dp_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = analogix_dp_detect,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -92,7 +92,6 @@ dumb_vga_connector_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs dumb_vga_con_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = dumb_vga_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -193,7 +193,6 @@ static enum drm_connector_status ge_b850v3_lvds_detect(
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = ge_b850v3_lvds_detect,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -238,7 +238,6 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs =
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs ptn3460_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -50,7 +50,6 @@ panel_bridge_connector_helper_funcs = {
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs panel_bridge_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
@ -195,3 +194,33 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge)
|
||||
devm_kfree(panel_bridge->panel->dev, bridge);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_panel_bridge_remove);
|
||||
|
||||
static void devm_drm_panel_bridge_release(struct device *dev, void *res)
|
||||
{
|
||||
struct drm_bridge **bridge = res;
|
||||
|
||||
drm_panel_bridge_remove(*bridge);
|
||||
}
|
||||
|
||||
struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
|
||||
struct drm_panel *panel,
|
||||
u32 connector_type)
|
||||
{
|
||||
struct drm_bridge **ptr, *bridge;
|
||||
|
||||
ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
|
||||
GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
bridge = drm_panel_bridge_add(panel, connector_type);
|
||||
if (!IS_ERR(bridge)) {
|
||||
*ptr = bridge;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return bridge;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_drm_panel_bridge_add);
|
||||
|
@ -476,7 +476,6 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs ps8622_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -124,7 +124,6 @@ sii902x_connector_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs sii902x_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = sii902x_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -2,6 +2,7 @@ config DRM_DW_HDMI
|
||||
tristate
|
||||
select DRM_KMS_HELPER
|
||||
select REGMAP_MMIO
|
||||
select CEC_CORE if CEC_NOTIFIER
|
||||
|
||||
config DRM_DW_HDMI_AHB_AUDIO
|
||||
tristate "Synopsys Designware AHB Audio interface"
|
||||
@ -23,6 +24,15 @@ config DRM_DW_HDMI_I2S_AUDIO
|
||||
Support the I2S Audio interface which is part of the Synopsys
|
||||
Designware HDMI block.
|
||||
|
||||
config DRM_DW_HDMI_CEC
|
||||
tristate "Synopsis Designware CEC interface"
|
||||
depends on DRM_DW_HDMI
|
||||
select CEC_CORE
|
||||
select CEC_NOTIFIER
|
||||
help
|
||||
Support the CE interface which is part of the Synopsys
|
||||
Designware HDMI block.
|
||||
|
||||
config DRM_DW_MIPI_DSI
|
||||
tristate
|
||||
select DRM_KMS_HELPER
|
||||
|
@ -3,5 +3,6 @@
|
||||
obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
|
||||
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
|
||||
obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
|
||||
obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
|
||||
|
||||
obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
|
||||
|
327
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
Normal file
327
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Designware HDMI CEC driver
|
||||
*
|
||||
* Copyright (C) 2015-2017 Russell King.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include <media/cec.h>
|
||||
#include <media/cec-notifier.h>
|
||||
|
||||
#include "dw-hdmi-cec.h"
|
||||
|
||||
enum {
|
||||
HDMI_IH_CEC_STAT0 = 0x0106,
|
||||
HDMI_IH_MUTE_CEC_STAT0 = 0x0186,
|
||||
|
||||
HDMI_CEC_CTRL = 0x7d00,
|
||||
CEC_CTRL_START = BIT(0),
|
||||
CEC_CTRL_FRAME_TYP = 3 << 1,
|
||||
CEC_CTRL_RETRY = 0 << 1,
|
||||
CEC_CTRL_NORMAL = 1 << 1,
|
||||
CEC_CTRL_IMMED = 2 << 1,
|
||||
|
||||
HDMI_CEC_STAT = 0x7d01,
|
||||
CEC_STAT_DONE = BIT(0),
|
||||
CEC_STAT_EOM = BIT(1),
|
||||
CEC_STAT_NACK = BIT(2),
|
||||
CEC_STAT_ARBLOST = BIT(3),
|
||||
CEC_STAT_ERROR_INIT = BIT(4),
|
||||
CEC_STAT_ERROR_FOLL = BIT(5),
|
||||
CEC_STAT_WAKEUP = BIT(6),
|
||||
|
||||
HDMI_CEC_MASK = 0x7d02,
|
||||
HDMI_CEC_POLARITY = 0x7d03,
|
||||
HDMI_CEC_INT = 0x7d04,
|
||||
HDMI_CEC_ADDR_L = 0x7d05,
|
||||
HDMI_CEC_ADDR_H = 0x7d06,
|
||||
HDMI_CEC_TX_CNT = 0x7d07,
|
||||
HDMI_CEC_RX_CNT = 0x7d08,
|
||||
HDMI_CEC_TX_DATA0 = 0x7d10,
|
||||
HDMI_CEC_RX_DATA0 = 0x7d20,
|
||||
HDMI_CEC_LOCK = 0x7d30,
|
||||
HDMI_CEC_WKUPCTRL = 0x7d31,
|
||||
};
|
||||
|
||||
struct dw_hdmi_cec {
|
||||
struct dw_hdmi *hdmi;
|
||||
const struct dw_hdmi_cec_ops *ops;
|
||||
u32 addresses;
|
||||
struct cec_adapter *adap;
|
||||
struct cec_msg rx_msg;
|
||||
unsigned int tx_status;
|
||||
bool tx_done;
|
||||
bool rx_done;
|
||||
struct cec_notifier *notify;
|
||||
int irq;
|
||||
};
|
||||
|
||||
static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
|
||||
{
|
||||
cec->ops->write(cec->hdmi, val, offset);
|
||||
}
|
||||
|
||||
static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
|
||||
{
|
||||
return cec->ops->read(cec->hdmi, offset);
|
||||
}
|
||||
|
||||
static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
|
||||
{
|
||||
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
|
||||
|
||||
if (logical_addr == CEC_LOG_ADDR_INVALID)
|
||||
cec->addresses = 0;
|
||||
else
|
||||
cec->addresses |= BIT(logical_addr) | BIT(15);
|
||||
|
||||
dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
|
||||
dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
|
||||
u32 signal_free_time, struct cec_msg *msg)
|
||||
{
|
||||
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
|
||||
unsigned int i, ctrl;
|
||||
|
||||
switch (signal_free_time) {
|
||||
case CEC_SIGNAL_FREE_TIME_RETRY:
|
||||
ctrl = CEC_CTRL_RETRY;
|
||||
break;
|
||||
case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
|
||||
default:
|
||||
ctrl = CEC_CTRL_NORMAL;
|
||||
break;
|
||||
case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
|
||||
ctrl = CEC_CTRL_IMMED;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < msg->len; i++)
|
||||
dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
|
||||
|
||||
dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
|
||||
dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
|
||||
{
|
||||
struct cec_adapter *adap = data;
|
||||
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
|
||||
unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
|
||||
irqreturn_t ret = IRQ_HANDLED;
|
||||
|
||||
if (stat == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
|
||||
|
||||
if (stat & CEC_STAT_ERROR_INIT) {
|
||||
cec->tx_status = CEC_TX_STATUS_ERROR;
|
||||
cec->tx_done = true;
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
} else if (stat & CEC_STAT_DONE) {
|
||||
cec->tx_status = CEC_TX_STATUS_OK;
|
||||
cec->tx_done = true;
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
} else if (stat & CEC_STAT_NACK) {
|
||||
cec->tx_status = CEC_TX_STATUS_NACK;
|
||||
cec->tx_done = true;
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
if (stat & CEC_STAT_EOM) {
|
||||
unsigned int len, i;
|
||||
|
||||
len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
|
||||
if (len > sizeof(cec->rx_msg.msg))
|
||||
len = sizeof(cec->rx_msg.msg);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
cec->rx_msg.msg[i] =
|
||||
dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
|
||||
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
|
||||
|
||||
cec->rx_msg.len = len;
|
||||
smp_wmb();
|
||||
cec->rx_done = true;
|
||||
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
|
||||
{
|
||||
struct cec_adapter *adap = data;
|
||||
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
|
||||
|
||||
if (cec->tx_done) {
|
||||
cec->tx_done = false;
|
||||
cec_transmit_attempt_done(adap, cec->tx_status);
|
||||
}
|
||||
if (cec->rx_done) {
|
||||
cec->rx_done = false;
|
||||
smp_rmb();
|
||||
cec_received_msg(adap, &cec->rx_msg);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
|
||||
{
|
||||
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
|
||||
|
||||
if (!enable) {
|
||||
dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
|
||||
dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
|
||||
|
||||
cec->ops->disable(cec->hdmi);
|
||||
} else {
|
||||
unsigned int irqs;
|
||||
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
|
||||
dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
|
||||
|
||||
dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
|
||||
|
||||
cec->ops->enable(cec->hdmi);
|
||||
|
||||
irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
|
||||
CEC_STAT_DONE;
|
||||
dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
|
||||
dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
|
||||
dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cec_adap_ops dw_hdmi_cec_ops = {
|
||||
.adap_enable = dw_hdmi_cec_enable,
|
||||
.adap_log_addr = dw_hdmi_cec_log_addr,
|
||||
.adap_transmit = dw_hdmi_cec_transmit,
|
||||
};
|
||||
|
||||
static void dw_hdmi_cec_del(void *data)
|
||||
{
|
||||
struct dw_hdmi_cec *cec = data;
|
||||
|
||||
cec_delete_adapter(cec->adap);
|
||||
}
|
||||
|
||||
static int dw_hdmi_cec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
|
||||
struct dw_hdmi_cec *cec;
|
||||
int ret;
|
||||
|
||||
if (!data)
|
||||
return -ENXIO;
|
||||
|
||||
/*
|
||||
* Our device is just a convenience - we want to link to the real
|
||||
* hardware device here, so that userspace can see the association
|
||||
* between the HDMI hardware and its associated CEC chardev.
|
||||
*/
|
||||
cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
|
||||
if (!cec)
|
||||
return -ENOMEM;
|
||||
|
||||
cec->irq = data->irq;
|
||||
cec->ops = data->ops;
|
||||
cec->hdmi = data->hdmi;
|
||||
|
||||
platform_set_drvdata(pdev, cec);
|
||||
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
|
||||
dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
|
||||
dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
|
||||
dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
|
||||
|
||||
cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
|
||||
CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
|
||||
CEC_CAP_RC | CEC_CAP_PASSTHROUGH,
|
||||
CEC_MAX_LOG_ADDRS);
|
||||
if (IS_ERR(cec->adap))
|
||||
return PTR_ERR(cec->adap);
|
||||
|
||||
/* override the module pointer */
|
||||
cec->adap->owner = THIS_MODULE;
|
||||
|
||||
ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
|
||||
if (ret) {
|
||||
cec_delete_adapter(cec->adap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
|
||||
dw_hdmi_cec_hardirq,
|
||||
dw_hdmi_cec_thread, IRQF_SHARED,
|
||||
"dw-hdmi-cec", cec->adap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
cec->notify = cec_notifier_get(pdev->dev.parent);
|
||||
if (!cec->notify)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = cec_register_adapter(cec->adap, pdev->dev.parent);
|
||||
if (ret < 0) {
|
||||
cec_notifier_put(cec->notify);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* CEC documentation says we must not call cec_delete_adapter
|
||||
* after a successful call to cec_register_adapter().
|
||||
*/
|
||||
devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
|
||||
|
||||
cec_register_cec_notifier(cec->adap, cec->notify);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_hdmi_cec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
|
||||
|
||||
cec_unregister_adapter(cec->adap);
|
||||
cec_notifier_put(cec->notify);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver dw_hdmi_cec_driver = {
|
||||
.probe = dw_hdmi_cec_probe,
|
||||
.remove = dw_hdmi_cec_remove,
|
||||
.driver = {
|
||||
.name = "dw-hdmi-cec",
|
||||
},
|
||||
};
|
||||
module_platform_driver(dw_hdmi_cec_driver);
|
||||
|
||||
MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
|
||||
MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
|
19
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
Normal file
19
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef DW_HDMI_CEC_H
|
||||
#define DW_HDMI_CEC_H
|
||||
|
||||
struct dw_hdmi;
|
||||
|
||||
struct dw_hdmi_cec_ops {
|
||||
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
|
||||
u8 (*read)(struct dw_hdmi *hdmi, int offset);
|
||||
void (*enable)(struct dw_hdmi *hdmi);
|
||||
void (*disable)(struct dw_hdmi *hdmi);
|
||||
};
|
||||
|
||||
struct dw_hdmi_cec_data {
|
||||
struct dw_hdmi *hdmi;
|
||||
const struct dw_hdmi_cec_ops *ops;
|
||||
int irq;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,7 +1,8 @@
|
||||
/*
|
||||
* dw-hdmi-i2s-audio.c
|
||||
*
|
||||
* Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
* Copyright (c) 2017 Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -35,8 +35,12 @@
|
||||
|
||||
#include "dw-hdmi.h"
|
||||
#include "dw-hdmi-audio.h"
|
||||
#include "dw-hdmi-cec.h"
|
||||
|
||||
#include <media/cec-notifier.h>
|
||||
|
||||
#define DDC_SEGMENT_ADDR 0x30
|
||||
|
||||
#define HDMI_EDID_LEN 512
|
||||
|
||||
enum hdmi_datamap {
|
||||
@ -130,6 +134,7 @@ struct dw_hdmi {
|
||||
unsigned int version;
|
||||
|
||||
struct platform_device *audio;
|
||||
struct platform_device *cec;
|
||||
struct device *dev;
|
||||
struct clk *isfr_clk;
|
||||
struct clk *iahb_clk;
|
||||
@ -163,6 +168,7 @@ struct dw_hdmi {
|
||||
bool bridge_is_on; /* indicates the bridge is on */
|
||||
bool rxsense; /* rxsense state */
|
||||
u8 phy_mask; /* desired phy int mask settings */
|
||||
u8 mc_clkdis; /* clock disable register */
|
||||
|
||||
spinlock_t audio_lock;
|
||||
struct mutex audio_mutex;
|
||||
@ -175,6 +181,8 @@ struct dw_hdmi {
|
||||
struct regmap *regm;
|
||||
void (*enable_audio)(struct dw_hdmi *hdmi);
|
||||
void (*disable_audio)(struct dw_hdmi *hdmi);
|
||||
|
||||
struct cec_notifier *cec_notifier;
|
||||
};
|
||||
|
||||
#define HDMI_IH_PHY_STAT0_RX_SENSE \
|
||||
@ -546,8 +554,11 @@ EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
|
||||
|
||||
static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
|
||||
{
|
||||
hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE,
|
||||
HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
|
||||
if (enable)
|
||||
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||||
else
|
||||
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
}
|
||||
|
||||
static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
|
||||
@ -1569,8 +1580,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
||||
/* HDMI Initialization Step B.4 */
|
||||
static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
|
||||
{
|
||||
u8 clkdis;
|
||||
|
||||
/* control period minimum duration */
|
||||
hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
|
||||
hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
|
||||
@ -1582,17 +1591,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
|
||||
hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
|
||||
|
||||
/* Enable pixel clock and tmds data path */
|
||||
clkdis = 0x7F;
|
||||
clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
|
||||
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
|
||||
HDMI_MC_CLKDIS_CSCCLK_DISABLE |
|
||||
HDMI_MC_CLKDIS_AUDCLK_DISABLE |
|
||||
HDMI_MC_CLKDIS_PREPCLK_DISABLE |
|
||||
HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
|
||||
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
|
||||
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
/* Enable csc path */
|
||||
if (is_color_space_conversion(hdmi)) {
|
||||
clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
|
||||
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
}
|
||||
|
||||
/* Enable color space conversion if needed */
|
||||
@ -1783,7 +1796,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
|
||||
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
|
||||
|
||||
@ -1896,6 +1908,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
|
||||
drm_mode_connector_update_edid_property(connector, edid);
|
||||
cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
/* Store the ELD */
|
||||
drm_edid_to_eld(connector, edid);
|
||||
@ -1920,7 +1933,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = dw_hdmi_connector_detect,
|
||||
.destroy = drm_connector_cleanup,
|
||||
@ -2119,11 +2131,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
|
||||
* ask the source to re-read the EDID.
|
||||
*/
|
||||
if (intr_stat &
|
||||
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
|
||||
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
|
||||
__dw_hdmi_setup_rx_sense(hdmi,
|
||||
phy_stat & HDMI_PHY_HPD,
|
||||
phy_stat & HDMI_PHY_RX_SENSE);
|
||||
|
||||
if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
|
||||
cec_notifier_set_phys_addr(hdmi->cec_notifier,
|
||||
CEC_PHYS_ADDR_INVALID);
|
||||
}
|
||||
|
||||
if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
|
||||
dev_dbg(hdmi->dev, "EVENT=%s\n",
|
||||
phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
|
||||
@ -2170,6 +2187,7 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
|
||||
.name = "DWC HDMI 2.0 TX PHY",
|
||||
.gen = 2,
|
||||
.has_svsret = true,
|
||||
.configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
|
||||
}, {
|
||||
.type = DW_HDMI_PHY_VENDOR_PHY,
|
||||
.name = "Vendor PHY",
|
||||
@ -2219,6 +2237,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
|
||||
{
|
||||
mutex_lock(&hdmi->mutex);
|
||||
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
|
||||
static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
|
||||
{
|
||||
mutex_lock(&hdmi->mutex);
|
||||
hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
||||
mutex_unlock(&hdmi->mutex);
|
||||
}
|
||||
|
||||
static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
|
||||
.write = hdmi_writeb,
|
||||
.read = hdmi_readb,
|
||||
.enable = dw_hdmi_cec_enable,
|
||||
.disable = dw_hdmi_cec_disable,
|
||||
};
|
||||
|
||||
static const struct regmap_config hdmi_regmap_8bit_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
@ -2241,6 +2282,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
||||
struct device_node *np = dev->of_node;
|
||||
struct platform_device_info pdevinfo;
|
||||
struct device_node *ddc_node;
|
||||
struct dw_hdmi_cec_data cec;
|
||||
struct dw_hdmi *hdmi;
|
||||
struct resource *iores = NULL;
|
||||
int irq;
|
||||
@ -2261,6 +2303,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
||||
hdmi->disabled = true;
|
||||
hdmi->rxsense = true;
|
||||
hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
|
||||
hdmi->mc_clkdis = 0x7f;
|
||||
|
||||
mutex_init(&hdmi->mutex);
|
||||
mutex_init(&hdmi->audio_mutex);
|
||||
@ -2376,6 +2419,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
goto err_iahb;
|
||||
|
||||
hdmi->cec_notifier = cec_notifier_get(dev);
|
||||
if (!hdmi->cec_notifier) {
|
||||
ret = -ENOMEM;
|
||||
goto err_iahb;
|
||||
}
|
||||
|
||||
/*
|
||||
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
|
||||
* N and cts values before enabling phy
|
||||
@ -2438,6 +2487,19 @@ __dw_hdmi_probe(struct platform_device *pdev,
|
||||
hdmi->audio = platform_device_register_full(&pdevinfo);
|
||||
}
|
||||
|
||||
if (config0 & HDMI_CONFIG0_CEC) {
|
||||
cec.hdmi = hdmi;
|
||||
cec.ops = &dw_hdmi_cec_ops;
|
||||
cec.irq = irq;
|
||||
|
||||
pdevinfo.name = "dw-hdmi-cec";
|
||||
pdevinfo.data = &cec;
|
||||
pdevinfo.size_data = sizeof(cec);
|
||||
pdevinfo.dma_mask = 0;
|
||||
|
||||
hdmi->cec = platform_device_register_full(&pdevinfo);
|
||||
}
|
||||
|
||||
/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
|
||||
if (hdmi->i2c)
|
||||
dw_hdmi_i2c_init(hdmi);
|
||||
@ -2452,6 +2514,9 @@ err_iahb:
|
||||
hdmi->ddc = NULL;
|
||||
}
|
||||
|
||||
if (hdmi->cec_notifier)
|
||||
cec_notifier_put(hdmi->cec_notifier);
|
||||
|
||||
clk_disable_unprepare(hdmi->iahb_clk);
|
||||
err_isfr:
|
||||
clk_disable_unprepare(hdmi->isfr_clk);
|
||||
@ -2465,10 +2530,15 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
|
||||
{
|
||||
if (hdmi->audio && !IS_ERR(hdmi->audio))
|
||||
platform_device_unregister(hdmi->audio);
|
||||
if (!IS_ERR(hdmi->cec))
|
||||
platform_device_unregister(hdmi->cec);
|
||||
|
||||
/* Disable all interrupts */
|
||||
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
|
||||
|
||||
if (hdmi->cec_notifier)
|
||||
cec_notifier_put(hdmi->cec_notifier);
|
||||
|
||||
clk_disable_unprepare(hdmi->iahb_clk);
|
||||
clk_disable_unprepare(hdmi->isfr_clk);
|
||||
|
||||
|
@ -478,51 +478,6 @@
|
||||
#define HDMI_A_PRESETUP 0x501A
|
||||
#define HDMI_A_SRM_BASE 0x5020
|
||||
|
||||
/* CEC Engine Registers */
|
||||
#define HDMI_CEC_CTRL 0x7D00
|
||||
#define HDMI_CEC_STAT 0x7D01
|
||||
#define HDMI_CEC_MASK 0x7D02
|
||||
#define HDMI_CEC_POLARITY 0x7D03
|
||||
#define HDMI_CEC_INT 0x7D04
|
||||
#define HDMI_CEC_ADDR_L 0x7D05
|
||||
#define HDMI_CEC_ADDR_H 0x7D06
|
||||
#define HDMI_CEC_TX_CNT 0x7D07
|
||||
#define HDMI_CEC_RX_CNT 0x7D08
|
||||
#define HDMI_CEC_TX_DATA0 0x7D10
|
||||
#define HDMI_CEC_TX_DATA1 0x7D11
|
||||
#define HDMI_CEC_TX_DATA2 0x7D12
|
||||
#define HDMI_CEC_TX_DATA3 0x7D13
|
||||
#define HDMI_CEC_TX_DATA4 0x7D14
|
||||
#define HDMI_CEC_TX_DATA5 0x7D15
|
||||
#define HDMI_CEC_TX_DATA6 0x7D16
|
||||
#define HDMI_CEC_TX_DATA7 0x7D17
|
||||
#define HDMI_CEC_TX_DATA8 0x7D18
|
||||
#define HDMI_CEC_TX_DATA9 0x7D19
|
||||
#define HDMI_CEC_TX_DATA10 0x7D1a
|
||||
#define HDMI_CEC_TX_DATA11 0x7D1b
|
||||
#define HDMI_CEC_TX_DATA12 0x7D1c
|
||||
#define HDMI_CEC_TX_DATA13 0x7D1d
|
||||
#define HDMI_CEC_TX_DATA14 0x7D1e
|
||||
#define HDMI_CEC_TX_DATA15 0x7D1f
|
||||
#define HDMI_CEC_RX_DATA0 0x7D20
|
||||
#define HDMI_CEC_RX_DATA1 0x7D21
|
||||
#define HDMI_CEC_RX_DATA2 0x7D22
|
||||
#define HDMI_CEC_RX_DATA3 0x7D23
|
||||
#define HDMI_CEC_RX_DATA4 0x7D24
|
||||
#define HDMI_CEC_RX_DATA5 0x7D25
|
||||
#define HDMI_CEC_RX_DATA6 0x7D26
|
||||
#define HDMI_CEC_RX_DATA7 0x7D27
|
||||
#define HDMI_CEC_RX_DATA8 0x7D28
|
||||
#define HDMI_CEC_RX_DATA9 0x7D29
|
||||
#define HDMI_CEC_RX_DATA10 0x7D2a
|
||||
#define HDMI_CEC_RX_DATA11 0x7D2b
|
||||
#define HDMI_CEC_RX_DATA12 0x7D2c
|
||||
#define HDMI_CEC_RX_DATA13 0x7D2d
|
||||
#define HDMI_CEC_RX_DATA14 0x7D2e
|
||||
#define HDMI_CEC_RX_DATA15 0x7D2f
|
||||
#define HDMI_CEC_LOCK 0x7D30
|
||||
#define HDMI_CEC_WKUPCTRL 0x7D31
|
||||
|
||||
/* I2C Master Registers (E-DDC) */
|
||||
#define HDMI_I2CM_SLAVE 0x7E00
|
||||
#define HDMI_I2CM_ADDRESS 0x7E01
|
||||
@ -555,6 +510,7 @@ enum {
|
||||
|
||||
/* CONFIG0_ID field values */
|
||||
HDMI_CONFIG0_I2S = 0x10,
|
||||
HDMI_CONFIG0_CEC = 0x02,
|
||||
|
||||
/* CONFIG1_ID field values */
|
||||
HDMI_CONFIG1_AHB = 0x01,
|
||||
|
@ -1160,7 +1160,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs tc_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -102,7 +102,6 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs tfp410_con_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = tfp410_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
|
@ -96,7 +96,6 @@
|
||||
|
||||
struct cirrus_crtc {
|
||||
struct drm_crtc base;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
int last_dpms;
|
||||
bool enabled;
|
||||
};
|
||||
@ -180,13 +179,6 @@ cirrus_bo(struct ttm_buffer_object *bo)
|
||||
#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
|
||||
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
|
||||
|
||||
/* cirrus_mode.c */
|
||||
void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno);
|
||||
void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, int regno);
|
||||
|
||||
|
||||
/* cirrus_main.c */
|
||||
int cirrus_device_init(struct cirrus_device *cdev,
|
||||
struct drm_device *ddev,
|
||||
|
@ -264,8 +264,6 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs cirrus_fb_helper_funcs = {
|
||||
.gamma_set = cirrus_crtc_fb_gamma_set,
|
||||
.gamma_get = cirrus_crtc_fb_gamma_get,
|
||||
.fb_probe = cirrusfb_create,
|
||||
};
|
||||
|
||||
|
@ -31,25 +31,6 @@
|
||||
* This file contains setup code for the CRTC.
|
||||
*/
|
||||
|
||||
static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
|
||||
{
|
||||
struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct cirrus_device *cdev = dev->dev_private;
|
||||
int i;
|
||||
|
||||
if (!crtc->enabled)
|
||||
return;
|
||||
|
||||
for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
|
||||
/* VGA registers */
|
||||
WREG8(PALETTE_INDEX, i);
|
||||
WREG8(PALETTE_DATA, cirrus_crtc->lut_r[i]);
|
||||
WREG8(PALETTE_DATA, cirrus_crtc->lut_g[i]);
|
||||
WREG8(PALETTE_DATA, cirrus_crtc->lut_b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The DRM core requires DPMS functions, but they make little sense in our
|
||||
* case and so are just stubs
|
||||
@ -330,15 +311,25 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct cirrus_device *cdev = dev->dev_private;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
cirrus_crtc->lut_r[i] = red[i];
|
||||
cirrus_crtc->lut_g[i] = green[i];
|
||||
cirrus_crtc->lut_b[i] = blue[i];
|
||||
if (!crtc->enabled)
|
||||
return 0;
|
||||
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
|
||||
for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
|
||||
/* VGA registers */
|
||||
WREG8(PALETTE_INDEX, i);
|
||||
WREG8(PALETTE_DATA, *r++ >> 8);
|
||||
WREG8(PALETTE_DATA, *g++ >> 8);
|
||||
WREG8(PALETTE_DATA, *b++ >> 8);
|
||||
}
|
||||
cirrus_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -365,7 +356,6 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
|
||||
.mode_set_base = cirrus_crtc_mode_set_base,
|
||||
.prepare = cirrus_crtc_prepare,
|
||||
.commit = cirrus_crtc_commit,
|
||||
.load_lut = cirrus_crtc_load_lut,
|
||||
};
|
||||
|
||||
/* CRTC setup */
|
||||
@ -373,7 +363,6 @@ static void cirrus_crtc_init(struct drm_device *dev)
|
||||
{
|
||||
struct cirrus_device *cdev = dev->dev_private;
|
||||
struct cirrus_crtc *cirrus_crtc;
|
||||
int i;
|
||||
|
||||
cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
|
||||
(CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
|
||||
@ -387,37 +376,9 @@ static void cirrus_crtc_init(struct drm_device *dev)
|
||||
drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
|
||||
cdev->mode_info.crtc = cirrus_crtc;
|
||||
|
||||
for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
|
||||
cirrus_crtc->lut_r[i] = i;
|
||||
cirrus_crtc->lut_g[i] = i;
|
||||
cirrus_crtc->lut_b[i] = i;
|
||||
}
|
||||
|
||||
drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
|
||||
}
|
||||
|
||||
/** Sets the color ramps on behalf of fbcon */
|
||||
void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
|
||||
|
||||
cirrus_crtc->lut_r[regno] = red;
|
||||
cirrus_crtc->lut_g[regno] = green;
|
||||
cirrus_crtc->lut_b[regno] = blue;
|
||||
}
|
||||
|
||||
/** Gets the color ramps on behalf of fbcon */
|
||||
void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, int regno)
|
||||
{
|
||||
struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
|
||||
|
||||
*red = cirrus_crtc->lut_r[regno];
|
||||
*green = cirrus_crtc->lut_g[regno];
|
||||
*blue = cirrus_crtc->lut_b[regno];
|
||||
}
|
||||
|
||||
static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
|
@ -713,7 +713,7 @@ EXPORT_SYMBOL(drm_atomic_get_plane_state);
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||
static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||
struct drm_plane_state *state, struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
@ -770,7 +770,6 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_plane_set_property);
|
||||
|
||||
/**
|
||||
* drm_atomic_plane_get_property - get property value from plane state
|
||||
@ -1145,7 +1144,7 @@ EXPORT_SYMBOL(drm_atomic_get_connector_state);
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||
static int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||
struct drm_connector_state *state, struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
@ -1212,7 +1211,6 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_connector_set_property);
|
||||
|
||||
static void drm_atomic_connector_print_state(struct drm_printer *p,
|
||||
const struct drm_connector_state *state)
|
||||
@ -1589,38 +1587,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_add_affected_planes);
|
||||
|
||||
/**
|
||||
* drm_atomic_legacy_backoff - locking backoff for legacy ioctls
|
||||
* @state: atomic state
|
||||
*
|
||||
* This function should be used by legacy entry points which don't understand
|
||||
* -EDEADLK semantics. For simplicity this one will grab all modeset locks after
|
||||
* the slowpath completed.
|
||||
*/
|
||||
void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_device *dev = state->dev;
|
||||
int ret;
|
||||
bool global = false;
|
||||
|
||||
if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
|
||||
global = true;
|
||||
|
||||
dev->mode_config.acquire_ctx = NULL;
|
||||
}
|
||||
|
||||
retry:
|
||||
drm_modeset_backoff(state->acquire_ctx);
|
||||
|
||||
ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
if (global)
|
||||
dev->mode_config.acquire_ctx = state->acquire_ctx;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_legacy_backoff);
|
||||
|
||||
/**
|
||||
* drm_atomic_check_only - check whether a given config would work
|
||||
* @state: atomic configuration to check
|
||||
@ -1864,9 +1830,60 @@ static struct drm_pending_vblank_event *create_vblank_event(
|
||||
return e;
|
||||
}
|
||||
|
||||
static int atomic_set_prop(struct drm_atomic_state *state,
|
||||
struct drm_mode_object *obj, struct drm_property *prop,
|
||||
uint64_t prop_value)
|
||||
int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
|
||||
struct drm_connector *connector,
|
||||
int mode)
|
||||
{
|
||||
struct drm_connector *tmp_connector;
|
||||
struct drm_connector_state *new_conn_state;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int i, ret, old_mode = connector->dpms;
|
||||
bool active = false;
|
||||
|
||||
ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
|
||||
state->acquire_ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
connector->dpms = mode;
|
||||
|
||||
crtc = connector->state->crtc;
|
||||
if (!crtc)
|
||||
goto out;
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
crtc_state = drm_atomic_get_crtc_state(state, crtc);
|
||||
if (IS_ERR(crtc_state)) {
|
||||
ret = PTR_ERR(crtc_state);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
|
||||
if (new_conn_state->crtc != crtc)
|
||||
continue;
|
||||
if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
crtc_state->active = active;
|
||||
ret = drm_atomic_commit(state);
|
||||
out:
|
||||
if (ret != 0)
|
||||
connector->dpms = old_mode;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||
struct drm_mode_object *obj,
|
||||
struct drm_property *prop,
|
||||
uint64_t prop_value)
|
||||
{
|
||||
struct drm_mode_object *ref;
|
||||
int ret;
|
||||
@ -2286,7 +2303,8 @@ retry:
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = atomic_set_prop(state, obj, prop, prop_value);
|
||||
ret = drm_atomic_set_property(state, obj, prop,
|
||||
prop_value);
|
||||
if (ret) {
|
||||
drm_mode_object_put(obj);
|
||||
goto out;
|
||||
|
@ -921,16 +921,12 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
|
||||
crtc = new_conn_state->crtc;
|
||||
if ((!crtc && old_conn_state->crtc) ||
|
||||
(crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
|
||||
struct drm_property *dpms_prop =
|
||||
dev->mode_config.dpms_property;
|
||||
int mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (crtc && crtc->state->active)
|
||||
mode = DRM_MODE_DPMS_ON;
|
||||
|
||||
connector->dpms = mode;
|
||||
drm_object_property_set_value(&connector->base,
|
||||
dpms_prop, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1270,7 +1266,7 @@ void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
|
||||
struct drm_crtc *crtc;
|
||||
int i;
|
||||
|
||||
for_each_crtc_in_state(old_state, crtc, unused, i) {
|
||||
for_each_new_crtc_in_state(old_state, crtc, unused, i) {
|
||||
struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
|
||||
int ret;
|
||||
|
||||
@ -2957,171 +2953,6 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_resume);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_crtc_set_property - helper for crtc properties
|
||||
* @crtc: DRM crtc
|
||||
* @property: DRM property
|
||||
* @val: value of property
|
||||
*
|
||||
* Provides a default crtc set_property handler using the atomic driver
|
||||
* interface.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
int
|
||||
drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int ret = 0;
|
||||
|
||||
state = drm_atomic_state_alloc(crtc->dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
/* ->set_property is always called with all locks held. */
|
||||
state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
|
||||
retry:
|
||||
crtc_state = drm_atomic_get_crtc_state(state, crtc);
|
||||
if (IS_ERR(crtc_state)) {
|
||||
ret = PTR_ERR(crtc_state);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = drm_atomic_crtc_set_property(crtc, crtc_state,
|
||||
property, val);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
fail:
|
||||
if (ret == -EDEADLK)
|
||||
goto backoff;
|
||||
|
||||
drm_atomic_state_put(state);
|
||||
return ret;
|
||||
|
||||
backoff:
|
||||
drm_atomic_state_clear(state);
|
||||
drm_atomic_legacy_backoff(state);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_plane_set_property - helper for plane properties
|
||||
* @plane: DRM plane
|
||||
* @property: DRM property
|
||||
* @val: value of property
|
||||
*
|
||||
* Provides a default plane set_property handler using the atomic driver
|
||||
* interface.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
int
|
||||
drm_atomic_helper_plane_set_property(struct drm_plane *plane,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_plane_state *plane_state;
|
||||
int ret = 0;
|
||||
|
||||
state = drm_atomic_state_alloc(plane->dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
/* ->set_property is always called with all locks held. */
|
||||
state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
|
||||
retry:
|
||||
plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
if (IS_ERR(plane_state)) {
|
||||
ret = PTR_ERR(plane_state);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = drm_atomic_plane_set_property(plane, plane_state,
|
||||
property, val);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
fail:
|
||||
if (ret == -EDEADLK)
|
||||
goto backoff;
|
||||
|
||||
drm_atomic_state_put(state);
|
||||
return ret;
|
||||
|
||||
backoff:
|
||||
drm_atomic_state_clear(state);
|
||||
drm_atomic_legacy_backoff(state);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_connector_set_property - helper for connector properties
|
||||
* @connector: DRM connector
|
||||
* @property: DRM property
|
||||
* @val: value of property
|
||||
*
|
||||
* Provides a default connector set_property handler using the atomic driver
|
||||
* interface.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
int
|
||||
drm_atomic_helper_connector_set_property(struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_connector_state *connector_state;
|
||||
int ret = 0;
|
||||
|
||||
state = drm_atomic_state_alloc(connector->dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
/* ->set_property is always called with all locks held. */
|
||||
state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
|
||||
retry:
|
||||
connector_state = drm_atomic_get_connector_state(state, connector);
|
||||
if (IS_ERR(connector_state)) {
|
||||
ret = PTR_ERR(connector_state);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = drm_atomic_connector_set_property(connector, connector_state,
|
||||
property, val);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
fail:
|
||||
if (ret == -EDEADLK)
|
||||
goto backoff;
|
||||
|
||||
drm_atomic_state_put(state);
|
||||
return ret;
|
||||
|
||||
backoff:
|
||||
drm_atomic_state_clear(state);
|
||||
drm_atomic_legacy_backoff(state);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
|
||||
|
||||
static int page_flip_common(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
@ -3256,85 +3087,6 @@ fail:
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_connector_dpms() - connector dpms helper implementation
|
||||
* @connector: affected connector
|
||||
* @mode: DPMS mode
|
||||
*
|
||||
* This is the main helper function provided by the atomic helper framework for
|
||||
* implementing the legacy DPMS connector interface. It computes the new desired
|
||||
* &drm_crtc_state.active state for the corresponding CRTC (if the connector is
|
||||
* enabled) and updates it.
|
||||
*
|
||||
* Returns:
|
||||
* Returns 0 on success, negative errno numbers on failure.
|
||||
*/
|
||||
int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
|
||||
int mode)
|
||||
{
|
||||
struct drm_mode_config *config = &connector->dev->mode_config;
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *tmp_connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int ret;
|
||||
bool active = false;
|
||||
int old_mode = connector->dpms;
|
||||
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
connector->dpms = mode;
|
||||
crtc = connector->state->crtc;
|
||||
|
||||
if (!crtc)
|
||||
return 0;
|
||||
|
||||
state = drm_atomic_state_alloc(connector->dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
|
||||
retry:
|
||||
crtc_state = drm_atomic_get_crtc_state(state, crtc);
|
||||
if (IS_ERR(crtc_state)) {
|
||||
ret = PTR_ERR(crtc_state);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
|
||||
|
||||
drm_connector_list_iter_begin(connector->dev, &conn_iter);
|
||||
drm_for_each_connector_iter(tmp_connector, &conn_iter) {
|
||||
if (tmp_connector->state->crtc != crtc)
|
||||
continue;
|
||||
|
||||
if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
crtc_state->active = active;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
fail:
|
||||
if (ret == -EDEADLK)
|
||||
goto backoff;
|
||||
if (ret != 0)
|
||||
connector->dpms = old_mode;
|
||||
drm_atomic_state_put(state);
|
||||
return ret;
|
||||
|
||||
backoff:
|
||||
drm_atomic_state_clear(state);
|
||||
drm_atomic_legacy_backoff(state);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_best_encoder - Helper for
|
||||
* &drm_connector_helper_funcs.best_encoder callback
|
||||
|
@ -717,9 +717,9 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
|
||||
* drivers, it remaps to controlling the "ACTIVE" property on the CRTC the
|
||||
* connector is linked to. Drivers should never set this property directly,
|
||||
* it is handled by the DRM core by calling the &drm_connector_funcs.dpms
|
||||
* callback. Atomic drivers should implement this hook using
|
||||
* drm_atomic_helper_connector_dpms(). This is the only property standard
|
||||
* connector property that userspace can change.
|
||||
* callback. For atomic drivers the remapping to the "ACTIVE" property is
|
||||
* implemented in the DRM core. This is the only standard connector
|
||||
* property that userspace can change.
|
||||
* PATH:
|
||||
* Connector path property to identify how this sink is physically
|
||||
* connected. Used by DP MST. This should be set by calling
|
||||
@ -1225,7 +1225,6 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
|
||||
} else if (connector->funcs->set_property)
|
||||
ret = connector->funcs->set_property(connector, property, value);
|
||||
|
||||
/* store the property value if successful */
|
||||
if (!ret)
|
||||
drm_object_property_set_value(&connector->base, property, value);
|
||||
return ret;
|
||||
|
@ -863,8 +863,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
|
||||
* provided by the driver.
|
||||
*
|
||||
* This function is deprecated. New drivers must implement atomic modeset
|
||||
* support, for which this function is unsuitable. Instead drivers should use
|
||||
* drm_atomic_helper_connector_dpms().
|
||||
* support, where DPMS is handled in the DRM core.
|
||||
*
|
||||
* Returns:
|
||||
* Always returns 0.
|
||||
|
@ -178,6 +178,13 @@ struct drm_minor;
|
||||
int drm_atomic_debugfs_init(struct drm_minor *minor);
|
||||
#endif
|
||||
|
||||
int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
|
||||
struct drm_connector *connector,
|
||||
int mode);
|
||||
int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||
struct drm_mode_object *obj,
|
||||
struct drm_property *prop,
|
||||
uint64_t prop_value);
|
||||
int drm_atomic_get_property(struct drm_mode_object *obj,
|
||||
struct drm_property *property, uint64_t *val);
|
||||
int drm_mode_atomic_ioctl(struct drm_device *dev,
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_gem.h>
|
||||
|
||||
#include "drm_crtc_internal.h"
|
||||
|
||||
@ -42,9 +43,10 @@
|
||||
* create dumb buffers suitable for scanout, which can then be used to create
|
||||
* KMS frame buffers.
|
||||
*
|
||||
* To support dumb objects drivers must implement the &drm_driver.dumb_create,
|
||||
* &drm_driver.dumb_destroy and &drm_driver.dumb_map_offset operations. See
|
||||
* there for further details.
|
||||
* To support dumb objects drivers must implement the &drm_driver.dumb_create
|
||||
* operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if
|
||||
* not set and &drm_driver.dumb_map_offset defaults to
|
||||
* drm_gem_dumb_map_offset(). See the callbacks for further details.
|
||||
*
|
||||
* Note that dumb objects may not be used for gpu acceleration, as has been
|
||||
* attempted on some ARM embedded platforms. Such drivers really must have
|
||||
@ -108,11 +110,16 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
|
||||
{
|
||||
struct drm_mode_map_dumb *args = data;
|
||||
|
||||
/* call driver ioctl to get mmap offset */
|
||||
if (!dev->driver->dumb_map_offset)
|
||||
if (!dev->driver->dumb_create)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
|
||||
if (dev->driver->dumb_map_offset)
|
||||
return dev->driver->dumb_map_offset(file_priv, dev,
|
||||
args->handle,
|
||||
&args->offset);
|
||||
else
|
||||
return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
|
||||
&args->offset);
|
||||
}
|
||||
|
||||
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
|
||||
@ -120,9 +127,12 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
|
||||
{
|
||||
struct drm_mode_destroy_dumb *args = data;
|
||||
|
||||
if (!dev->driver->dumb_destroy)
|
||||
if (!dev->driver->dumb_create)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->driver->dumb_destroy(file_priv, dev, args->handle);
|
||||
if (dev->driver->dumb_destroy)
|
||||
return dev->driver->dumb_destroy(file_priv, dev, args->handle);
|
||||
else
|
||||
return drm_gem_dumb_destroy(file_priv, dev, args->handle);
|
||||
}
|
||||
|
||||
|
@ -1821,17 +1821,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Set the fb pointer - usually drm_setup_crtcs does this for hotplug
|
||||
* events, but at init time drm_setup_crtcs needs to be called before
|
||||
* the fb is allocated (since we need to figure out the desired size of
|
||||
* the fb before we can allocate it ...). Hence we need to fix things up
|
||||
* here again.
|
||||
*/
|
||||
for (i = 0; i < fb_helper->crtc_count; i++)
|
||||
if (fb_helper->crtc_info[i].mode_set.num_connectors)
|
||||
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1893,8 +1882,6 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
|
||||
info->var.xoffset = 0;
|
||||
info->var.yoffset = 0;
|
||||
info->var.activate = FB_ACTIVATE_NOW;
|
||||
info->var.height = -1;
|
||||
info->var.width = -1;
|
||||
|
||||
switch (fb->format->depth) {
|
||||
case 8:
|
||||
@ -2410,9 +2397,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
|
||||
struct drm_display_mode *mode = modes[i];
|
||||
struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
|
||||
struct drm_fb_offset *offset = &offsets[i];
|
||||
struct drm_mode_set *modeset = &fb_crtc->mode_set;
|
||||
|
||||
if (mode && fb_crtc) {
|
||||
struct drm_mode_set *modeset = &fb_crtc->mode_set;
|
||||
struct drm_connector *connector =
|
||||
fb_helper->connector_info[i]->connector;
|
||||
|
||||
@ -2426,7 +2413,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
|
||||
fb_crtc->desired_mode);
|
||||
drm_connector_get(connector);
|
||||
modeset->connectors[modeset->num_connectors++] = connector;
|
||||
modeset->fb = fb_helper->fb;
|
||||
modeset->x = offset->x;
|
||||
modeset->y = offset->y;
|
||||
}
|
||||
@ -2438,6 +2424,37 @@ out:
|
||||
kfree(enabled);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a continuation of drm_setup_crtcs() that sets up anything related
|
||||
* to the framebuffer. During initialization, drm_setup_crtcs() is called before
|
||||
* the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev).
|
||||
* So, any setup that touches those fields needs to be done here instead of in
|
||||
* drm_setup_crtcs().
|
||||
*/
|
||||
static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
struct fb_info *info = fb_helper->fbdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fb_helper->crtc_count; i++)
|
||||
if (fb_helper->crtc_info[i].mode_set.num_connectors)
|
||||
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
|
||||
|
||||
mutex_lock(&fb_helper->dev->mode_config.mutex);
|
||||
drm_fb_helper_for_each_connector(fb_helper, i) {
|
||||
struct drm_connector *connector =
|
||||
fb_helper->connector_info[i]->connector;
|
||||
|
||||
/* use first connected connector for the physical dimensions */
|
||||
if (connector->status == connector_status_connected) {
|
||||
info->var.width = connector->display_info.width_mm;
|
||||
info->var.height = connector->display_info.height_mm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&fb_helper->dev->mode_config.mutex);
|
||||
}
|
||||
|
||||
/* Note: Drops fb_helper->lock before returning. */
|
||||
static int
|
||||
__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
|
||||
@ -2463,6 +2480,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
|
||||
|
||||
return ret;
|
||||
}
|
||||
drm_setup_crtcs_fb(fb_helper);
|
||||
|
||||
fb_helper->deferred_setup = false;
|
||||
|
||||
@ -2591,6 +2609,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
|
||||
drm_setup_crtcs_fb(fb_helper);
|
||||
mutex_unlock(&fb_helper->lock);
|
||||
|
||||
drm_fb_helper_set_par(fb_helper->fbdev);
|
||||
|
@ -310,6 +310,41 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_handle_delete);
|
||||
|
||||
/**
|
||||
* drm_gem_dumb_map_offset - return the fake mmap offset for a gem object
|
||||
* @file: drm file-private structure containing the gem object
|
||||
* @dev: corresponding drm_device
|
||||
* @handle: gem object handle
|
||||
* @offset: return location for the fake mmap offset
|
||||
*
|
||||
* This implements the &drm_driver.dumb_map_offset kms driver callback for
|
||||
* drivers which use gem to manage their backing storage.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
||||
u32 handle, u64 *offset)
|
||||
{
|
||||
struct drm_gem_object *obj;
|
||||
int ret;
|
||||
|
||||
obj = drm_gem_object_lookup(file, handle);
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
ret = drm_gem_create_mmap_offset(obj);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
*offset = drm_vma_node_offset_addr(&obj->vma_node);
|
||||
out:
|
||||
drm_gem_object_put_unlocked(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
|
||||
|
||||
/**
|
||||
* drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
|
||||
* @file: drm file-private structure to remove the dumb handle from
|
||||
|
@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
|
||||
return -ENOMEM;
|
||||
dev->mode_config.gamma_lut_size_property = prop;
|
||||
|
||||
prop = drm_property_create(dev,
|
||||
DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
|
||||
"IN_FORMATS", 0);
|
||||
if (!prop)
|
||||
return -ENOMEM;
|
||||
dev->mode_config.modifiers_property = prop;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -233,6 +233,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
|
||||
{
|
||||
int i;
|
||||
|
||||
WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
|
||||
!(property->flags & DRM_MODE_PROP_IMMUTABLE));
|
||||
|
||||
for (i = 0; i < obj->properties->count; i++) {
|
||||
if (obj->properties->properties[i] == property) {
|
||||
obj->properties->values[i] = val;
|
||||
@ -244,24 +247,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_object_property_set_value);
|
||||
|
||||
/**
|
||||
* drm_object_property_get_value - retrieve the value of a property
|
||||
* @obj: drm mode object to get property value from
|
||||
* @property: property to retrieve
|
||||
* @val: storage for the property value
|
||||
*
|
||||
* This function retrieves the softare state of the given property for the given
|
||||
* property. Since there is no driver callback to retrieve the current property
|
||||
* value this might be out of sync with the hardware, depending upon the driver
|
||||
* and property.
|
||||
*
|
||||
* Atomic drivers should never call this function directly, the core will read
|
||||
* out property values through the various ->atomic_get_property callbacks.
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success, error code on failure.
|
||||
*/
|
||||
int drm_object_property_get_value(struct drm_mode_object *obj,
|
||||
int __drm_object_property_get_value(struct drm_mode_object *obj,
|
||||
struct drm_property *property, uint64_t *val)
|
||||
{
|
||||
int i;
|
||||
@ -284,6 +270,31 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_object_property_get_value - retrieve the value of a property
|
||||
* @obj: drm mode object to get property value from
|
||||
* @property: property to retrieve
|
||||
* @val: storage for the property value
|
||||
*
|
||||
* This function retrieves the softare state of the given property for the given
|
||||
* property. Since there is no driver callback to retrieve the current property
|
||||
* value this might be out of sync with the hardware, depending upon the driver
|
||||
* and property.
|
||||
*
|
||||
* Atomic drivers should never call this function directly, the core will read
|
||||
* out property values through the various ->atomic_get_property callbacks.
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success, error code on failure.
|
||||
*/
|
||||
int drm_object_property_get_value(struct drm_mode_object *obj,
|
||||
struct drm_property *property, uint64_t *val)
|
||||
{
|
||||
WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
|
||||
|
||||
return __drm_object_property_get_value(obj, property, val);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_object_property_get_value);
|
||||
|
||||
/* helper for getconnector and getproperties ioctls */
|
||||
@ -302,7 +313,7 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
|
||||
continue;
|
||||
|
||||
if (*arg_count_props > count) {
|
||||
ret = drm_object_property_get_value(obj, prop, &val);
|
||||
ret = __drm_object_property_get_value(obj, prop, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -381,6 +392,83 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int set_property_legacy(struct drm_mode_object *obj,
|
||||
struct drm_property *prop,
|
||||
uint64_t prop_value)
|
||||
{
|
||||
struct drm_device *dev = prop->dev;
|
||||
struct drm_mode_object *ref;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!drm_property_change_valid_get(prop, prop_value, &ref))
|
||||
return -EINVAL;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
switch (obj->type) {
|
||||
case DRM_MODE_OBJECT_CONNECTOR:
|
||||
ret = drm_mode_connector_set_obj_prop(obj, prop,
|
||||
prop_value);
|
||||
break;
|
||||
case DRM_MODE_OBJECT_CRTC:
|
||||
ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
|
||||
break;
|
||||
case DRM_MODE_OBJECT_PLANE:
|
||||
ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
|
||||
prop, prop_value);
|
||||
break;
|
||||
}
|
||||
drm_property_change_valid_put(prop, ref);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_property_atomic(struct drm_mode_object *obj,
|
||||
struct drm_property *prop,
|
||||
uint64_t prop_value)
|
||||
{
|
||||
struct drm_device *dev = prop->dev;
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
int ret;
|
||||
|
||||
drm_modeset_acquire_init(&ctx, 0);
|
||||
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
state->acquire_ctx = &ctx;
|
||||
retry:
|
||||
if (prop == state->dev->mode_config.dpms_property) {
|
||||
if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = drm_atomic_connector_commit_dpms(state,
|
||||
obj_to_connector(obj),
|
||||
prop_value);
|
||||
} else {
|
||||
ret = drm_atomic_set_property(state, obj, prop, prop_value);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = drm_atomic_commit(state);
|
||||
}
|
||||
out:
|
||||
if (ret == -EDEADLK) {
|
||||
drm_atomic_state_clear(state);
|
||||
drm_modeset_backoff(&ctx);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
drm_atomic_state_put(state);
|
||||
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
@ -388,18 +476,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_mode_object *arg_obj;
|
||||
struct drm_property *property;
|
||||
int ret = -EINVAL;
|
||||
struct drm_mode_object *ref;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
return -EINVAL;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
|
||||
if (!arg_obj) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (!arg_obj)
|
||||
return -ENOENT;
|
||||
|
||||
if (!arg_obj->properties)
|
||||
goto out_unref;
|
||||
@ -408,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
||||
if (!property)
|
||||
goto out_unref;
|
||||
|
||||
if (!drm_property_change_valid_get(property, arg->value, &ref))
|
||||
goto out_unref;
|
||||
|
||||
switch (arg_obj->type) {
|
||||
case DRM_MODE_OBJECT_CONNECTOR:
|
||||
ret = drm_mode_connector_set_obj_prop(arg_obj, property,
|
||||
arg->value);
|
||||
break;
|
||||
case DRM_MODE_OBJECT_CRTC:
|
||||
ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
|
||||
break;
|
||||
case DRM_MODE_OBJECT_PLANE:
|
||||
ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
|
||||
property, arg->value);
|
||||
break;
|
||||
}
|
||||
|
||||
drm_property_change_valid_put(property, ref);
|
||||
if (drm_drv_uses_atomic_modeset(property->dev))
|
||||
ret = set_property_atomic(arg_obj, property, arg->value);
|
||||
else
|
||||
ret = set_property_legacy(arg_obj, property, arg->value);
|
||||
|
||||
out_unref:
|
||||
drm_mode_object_put(arg_obj);
|
||||
out:
|
||||
drm_modeset_unlock_all(dev);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1610,7 +1610,7 @@ out:
|
||||
* drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
|
||||
* output format
|
||||
*
|
||||
* @connector: drm connector under action.
|
||||
* @display: display under action
|
||||
* @mode: video mode to be tested.
|
||||
*
|
||||
* Returns:
|
||||
|
@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
|
||||
&drm_primary_helper_funcs,
|
||||
safe_modeset_formats,
|
||||
ARRAY_SIZE(safe_modeset_formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
|
@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev)
|
||||
return num;
|
||||
}
|
||||
|
||||
static inline u32 *
|
||||
formats_ptr(struct drm_format_modifier_blob *blob)
|
||||
{
|
||||
return (u32 *)(((char *)blob) + blob->formats_offset);
|
||||
}
|
||||
|
||||
static inline struct drm_format_modifier *
|
||||
modifiers_ptr(struct drm_format_modifier_blob *blob)
|
||||
{
|
||||
return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
|
||||
}
|
||||
|
||||
static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
|
||||
{
|
||||
const struct drm_mode_config *config = &dev->mode_config;
|
||||
struct drm_property_blob *blob;
|
||||
struct drm_format_modifier *mod;
|
||||
size_t blob_size, formats_size, modifiers_size;
|
||||
struct drm_format_modifier_blob *blob_data;
|
||||
unsigned int i, j;
|
||||
|
||||
formats_size = sizeof(__u32) * plane->format_count;
|
||||
if (WARN_ON(!formats_size)) {
|
||||
/* 0 formats are never expected */
|
||||
return 0;
|
||||
}
|
||||
|
||||
modifiers_size =
|
||||
sizeof(struct drm_format_modifier) * plane->modifier_count;
|
||||
|
||||
blob_size = sizeof(struct drm_format_modifier_blob);
|
||||
/* Modifiers offset is a pointer to a struct with a 64 bit field so it
|
||||
* should be naturally aligned to 8B.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
|
||||
blob_size += ALIGN(formats_size, 8);
|
||||
blob_size += modifiers_size;
|
||||
|
||||
blob = drm_property_create_blob(dev, blob_size, NULL);
|
||||
if (IS_ERR(blob))
|
||||
return -1;
|
||||
|
||||
blob_data = (struct drm_format_modifier_blob *)blob->data;
|
||||
blob_data->version = FORMAT_BLOB_CURRENT;
|
||||
blob_data->count_formats = plane->format_count;
|
||||
blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
|
||||
blob_data->count_modifiers = plane->modifier_count;
|
||||
|
||||
blob_data->modifiers_offset =
|
||||
ALIGN(blob_data->formats_offset + formats_size, 8);
|
||||
|
||||
memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
|
||||
|
||||
/* If we can't determine support, just bail */
|
||||
if (!plane->funcs->format_mod_supported)
|
||||
goto done;
|
||||
|
||||
mod = modifiers_ptr(blob_data);
|
||||
for (i = 0; i < plane->modifier_count; i++) {
|
||||
for (j = 0; j < plane->format_count; j++) {
|
||||
if (plane->funcs->format_mod_supported(plane,
|
||||
plane->format_types[j],
|
||||
plane->modifiers[i])) {
|
||||
|
||||
mod->formats |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
||||
mod->modifier = plane->modifiers[i];
|
||||
mod->offset = 0;
|
||||
mod->pad = 0;
|
||||
mod++;
|
||||
}
|
||||
|
||||
done:
|
||||
drm_object_attach_property(&plane->base, config->modifiers_property,
|
||||
blob->base.id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_universal_plane_init - Initialize a new universal plane object
|
||||
* @dev: DRM device
|
||||
@ -70,6 +151,8 @@ static unsigned int drm_num_planes(struct drm_device *dev)
|
||||
* @funcs: callbacks for the new plane
|
||||
* @formats: array of supported formats (DRM_FORMAT\_\*)
|
||||
* @format_count: number of elements in @formats
|
||||
* @format_modifiers: array of struct drm_format modifiers terminated by
|
||||
* DRM_FORMAT_MOD_INVALID
|
||||
* @type: type of plane (overlay, primary, cursor)
|
||||
* @name: printf style format string for the plane name, or NULL for default name
|
||||
*
|
||||
@ -82,10 +165,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
uint32_t possible_crtcs,
|
||||
const struct drm_plane_funcs *funcs,
|
||||
const uint32_t *formats, unsigned int format_count,
|
||||
const uint64_t *format_modifiers,
|
||||
enum drm_plane_type type,
|
||||
const char *name, ...)
|
||||
{
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
unsigned int format_modifier_count = 0;
|
||||
int ret;
|
||||
|
||||
ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
|
||||
@ -105,6 +190,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* First driver to need more than 64 formats needs to fix this. Each
|
||||
* format is encoded as a bit and the current code only supports a u64.
|
||||
*/
|
||||
if (WARN_ON(format_count > 64))
|
||||
return -EINVAL;
|
||||
|
||||
if (format_modifiers) {
|
||||
const uint64_t *temp_modifiers = format_modifiers;
|
||||
while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
|
||||
format_modifier_count++;
|
||||
}
|
||||
|
||||
plane->modifier_count = format_modifier_count;
|
||||
plane->modifiers = kmalloc_array(format_modifier_count,
|
||||
sizeof(format_modifiers[0]),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (format_modifier_count && !plane->modifiers) {
|
||||
DRM_DEBUG_KMS("out of memory when allocating plane\n");
|
||||
kfree(plane->format_types);
|
||||
drm_mode_object_unregister(dev, &plane->base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
va_list ap;
|
||||
|
||||
@ -117,12 +227,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
}
|
||||
if (!plane->name) {
|
||||
kfree(plane->format_types);
|
||||
kfree(plane->modifiers);
|
||||
drm_mode_object_unregister(dev, &plane->base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
|
||||
plane->format_count = format_count;
|
||||
memcpy(plane->modifiers, format_modifiers,
|
||||
format_modifier_count * sizeof(format_modifiers[0]));
|
||||
plane->possible_crtcs = possible_crtcs;
|
||||
plane->type = type;
|
||||
|
||||
@ -149,6 +262,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
|
||||
}
|
||||
|
||||
if (config->allow_fb_modifiers)
|
||||
create_in_format_blob(dev, plane);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_universal_plane_init);
|
||||
@ -205,7 +321,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
|
||||
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
||||
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
|
||||
formats, format_count, type, NULL);
|
||||
formats, format_count,
|
||||
NULL, type, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_init);
|
||||
|
||||
@ -224,6 +341,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
|
||||
drm_modeset_lock_fini(&plane->mutex);
|
||||
|
||||
kfree(plane->format_types);
|
||||
kfree(plane->modifiers);
|
||||
drm_mode_object_unregister(dev, &plane->base);
|
||||
|
||||
BUG_ON(list_empty(&plane->head));
|
||||
|
@ -194,19 +194,26 @@ EXPORT_SYMBOL(drm_scdc_set_scrambling);
|
||||
* @adapter: I2C adapter for DDC channel
|
||||
* @set: ret or reset the high clock ratio
|
||||
*
|
||||
* TMDS clock ratio calculations go like this:
|
||||
* TMDS character = 10 bit TMDS encoded value
|
||||
* TMDS character rate = The rate at which TMDS characters are transmitted(Mcsc)
|
||||
* TMDS bit rate = 10x TMDS character rate
|
||||
* As per the spec:
|
||||
* TMDS clock rate for pixel clock < 340 MHz = 1x the character rate
|
||||
* = 1/10 pixel clock rate
|
||||
* TMDS clock rate for pixel clock > 340 MHz = 0.25x the character rate
|
||||
* = 1/40 pixel clock rate
|
||||
*
|
||||
* Writes to the TMDS config register over SCDC channel, and:
|
||||
* sets TMDS clock ratio to 1/40 when set = 1
|
||||
* sets TMDS clock ratio to 1/10 when set = 0
|
||||
* TMDS clock ratio calculations go like this:
|
||||
* TMDS character = 10 bit TMDS encoded value
|
||||
*
|
||||
* TMDS character rate = The rate at which TMDS characters are
|
||||
* transmitted (Mcsc)
|
||||
*
|
||||
* TMDS bit rate = 10x TMDS character rate
|
||||
*
|
||||
* As per the spec:
|
||||
* TMDS clock rate for pixel clock < 340 MHz = 1x the character
|
||||
* rate = 1/10 pixel clock rate
|
||||
*
|
||||
* TMDS clock rate for pixel clock > 340 MHz = 0.25x the character
|
||||
* rate = 1/40 pixel clock rate
|
||||
*
|
||||
* Writes to the TMDS config register over SCDC channel, and:
|
||||
* sets TMDS clock ratio to 1/40 when set = 1
|
||||
*
|
||||
* sets TMDS clock ratio to 1/10 when set = 0
|
||||
*
|
||||
* Returns:
|
||||
* True if write is successful, false otherwise.
|
||||
|
@ -199,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
|
||||
* @funcs: callbacks for the display pipe (optional)
|
||||
* @formats: array of supported formats (DRM_FORMAT\_\*)
|
||||
* @format_count: number of elements in @formats
|
||||
* @format_modifiers: array of formats modifiers
|
||||
* @connector: connector to attach and register (optional)
|
||||
*
|
||||
* Sets up a display pipeline which consist of a really simple
|
||||
@ -219,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
|
||||
struct drm_simple_display_pipe *pipe,
|
||||
const struct drm_simple_display_pipe_funcs *funcs,
|
||||
const uint32_t *formats, unsigned int format_count,
|
||||
const uint64_t *format_modifiers,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_encoder *encoder = &pipe->encoder;
|
||||
@ -233,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
|
||||
ret = drm_universal_plane_init(dev, plane, 0,
|
||||
&drm_simple_kms_plane_funcs,
|
||||
formats, format_count,
|
||||
format_modifiers,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -59,7 +59,6 @@ static void exynos_dpi_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs exynos_dpi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = exynos_dpi_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = exynos_dpi_connector_destroy,
|
||||
|
@ -1537,7 +1537,6 @@ static void exynos_dsi_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = exynos_dsi_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = exynos_dsi_connector_destroy,
|
||||
|
@ -173,7 +173,6 @@ static struct drm_plane_funcs exynos_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.reset = exynos_drm_plane_reset,
|
||||
.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
|
||||
.atomic_destroy_state = exynos_drm_plane_destroy_state,
|
||||
@ -283,7 +282,7 @@ int exynos_plane_init(struct drm_device *dev,
|
||||
&exynos_plane_funcs,
|
||||
config->pixel_formats,
|
||||
config->num_pixel_formats,
|
||||
config->type, NULL);
|
||||
NULL, config->type, NULL);
|
||||
if (err) {
|
||||
DRM_ERROR("failed to initialize plane\n");
|
||||
return err;
|
||||
|
@ -289,7 +289,6 @@ static void vidi_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs vidi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = vidi_detect,
|
||||
.destroy = vidi_connector_destroy,
|
||||
|
@ -835,7 +835,6 @@ static void hdmi_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs hdmi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.detect = hdmi_detect,
|
||||
.destroy = hdmi_connector_destroy,
|
||||
|
@ -176,8 +176,6 @@ static struct drm_driver fsl_dcu_drm_driver = {
|
||||
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
|
||||
.gem_prime_mmap = drm_gem_cma_prime_mmap,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.fops = &fsl_dcu_drm_fops,
|
||||
.name = "fsl-dcu-drm",
|
||||
.desc = "Freescale DCU DRM",
|
||||
|
@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
|
||||
&fsl_dcu_drm_plane_funcs,
|
||||
fsl_dcu_drm_plane_formats,
|
||||
ARRAY_SIZE(fsl_dcu_drm_plane_formats),
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
|
@ -63,7 +63,6 @@ static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.destroy = fsl_dcu_drm_connector_destroy,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
};
|
||||
|
@ -479,26 +479,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
|
||||
return psb_framebuffer_create(dev, cmd, r);
|
||||
}
|
||||
|
||||
static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
|
||||
|
||||
gma_crtc->lut_r[regno] = red >> 8;
|
||||
gma_crtc->lut_g[regno] = green >> 8;
|
||||
gma_crtc->lut_b[regno] = blue >> 8;
|
||||
}
|
||||
|
||||
static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
|
||||
u16 *green, u16 *blue, int regno)
|
||||
{
|
||||
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
|
||||
|
||||
*red = gma_crtc->lut_r[regno] << 8;
|
||||
*green = gma_crtc->lut_g[regno] << 8;
|
||||
*blue = gma_crtc->lut_b[regno] << 8;
|
||||
}
|
||||
|
||||
static int psbfb_probe(struct drm_fb_helper *helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
@ -525,8 +505,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
|
||||
}
|
||||
|
||||
static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
|
||||
.gamma_set = psbfb_gamma_set,
|
||||
.gamma_get = psbfb_gamma_get,
|
||||
.fb_probe = psbfb_probe,
|
||||
};
|
||||
|
||||
|
@ -144,33 +144,32 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
|
||||
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
|
||||
const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
|
||||
int palreg = map->palette;
|
||||
u16 *r, *g, *b;
|
||||
int i;
|
||||
|
||||
/* The clocks have to be on to load the palette. */
|
||||
if (!crtc->enabled)
|
||||
return;
|
||||
|
||||
r = crtc->gamma_store;
|
||||
g = r + crtc->gamma_size;
|
||||
b = g + crtc->gamma_size;
|
||||
|
||||
if (gma_power_begin(dev, false)) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
REG_WRITE(palreg + 4 * i,
|
||||
((gma_crtc->lut_r[i] +
|
||||
gma_crtc->lut_adj[i]) << 16) |
|
||||
((gma_crtc->lut_g[i] +
|
||||
gma_crtc->lut_adj[i]) << 8) |
|
||||
(gma_crtc->lut_b[i] +
|
||||
gma_crtc->lut_adj[i]));
|
||||
(((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
|
||||
(((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
|
||||
((*b++ >> 8) + gma_crtc->lut_adj[i]));
|
||||
}
|
||||
gma_power_end(dev);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++) {
|
||||
/* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */
|
||||
dev_priv->regs.pipe[0].palette[i] =
|
||||
((gma_crtc->lut_r[i] +
|
||||
gma_crtc->lut_adj[i]) << 16) |
|
||||
((gma_crtc->lut_g[i] +
|
||||
gma_crtc->lut_adj[i]) << 8) |
|
||||
(gma_crtc->lut_b[i] +
|
||||
gma_crtc->lut_adj[i]);
|
||||
(((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
|
||||
(((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
|
||||
((*b++ >> 8) + gma_crtc->lut_adj[i]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -180,15 +179,6 @@ int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
|
||||
u32 size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
gma_crtc->lut_r[i] = red[i] >> 8;
|
||||
gma_crtc->lut_g[i] = green[i] >> 8;
|
||||
gma_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
|
||||
gma_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
|
@ -518,13 +518,8 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
|
||||
gma_crtc->pipe = pipe;
|
||||
gma_crtc->plane = pipe;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
gma_crtc->lut_r[i] = i;
|
||||
gma_crtc->lut_g[i] = i;
|
||||
gma_crtc->lut_b[i] = i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
gma_crtc->lut_adj[i] = 0;
|
||||
}
|
||||
|
||||
gma_crtc->mode_dev = mode_dev;
|
||||
gma_crtc->cursor_addr = 0;
|
||||
|
@ -172,7 +172,6 @@ struct gma_crtc {
|
||||
int plane;
|
||||
uint32_t cursor_addr;
|
||||
struct gtt_range *cursor_gt;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
u8 lut_adj[256];
|
||||
struct psb_intel_framebuffer *fbdev_fb;
|
||||
/* a mode_set for fbdev users on this crtc */
|
||||
|
@ -150,7 +150,6 @@ static const u32 channel_formats1[] = {
|
||||
static struct drm_plane_funcs hibmc_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
@ -181,6 +180,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
|
||||
ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
|
||||
channel_formats1,
|
||||
ARRAY_SIZE(channel_formats1),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
NULL);
|
||||
if (ret) {
|
||||
|
@ -67,7 +67,6 @@ static struct drm_driver hibmc_driver = {
|
||||
.gem_free_object_unlocked = hibmc_gem_free_object,
|
||||
.dumb_create = hibmc_dumb_create,
|
||||
.dumb_map_offset = hibmc_dumb_mmap_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.irq_handler = hibmc_drm_interrupt,
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,6 @@ static const struct drm_connector_helper_funcs
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs hibmc_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -567,7 +567,6 @@ static const struct drm_crtc_funcs ade_crtc_funcs = {
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
.set_property = drm_atomic_helper_crtc_set_property,
|
||||
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||
.enable_vblank = ade_crtc_enable_vblank,
|
||||
@ -890,7 +889,6 @@ static const struct drm_plane_helper_funcs ade_plane_helper_funcs = {
|
||||
static struct drm_plane_funcs ade_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
@ -910,7 +908,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane,
|
||||
return ret;
|
||||
|
||||
ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs,
|
||||
fmts, fmts_cnt, type, NULL);
|
||||
fmts, fmts_cnt, NULL, type, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch);
|
||||
return ret;
|
||||
|
@ -969,14 +969,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
|
||||
|
||||
/* DRM connector functions */
|
||||
|
||||
static int tda998x_connector_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC))
|
||||
return drm_atomic_helper_connector_dpms(connector, mode);
|
||||
else
|
||||
return drm_helper_connector_dpms(connector, mode);
|
||||
}
|
||||
|
||||
static int tda998x_connector_fill_modes(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY)
|
||||
{
|
||||
@ -1014,7 +1006,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs tda998x_connector_funcs = {
|
||||
.dpms = tda998x_connector_dpms,
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.fill_modes = tda998x_connector_fill_modes,
|
||||
.detect = tda998x_connector_detect,
|
||||
|
@ -2755,7 +2755,6 @@ static struct drm_driver driver = {
|
||||
|
||||
.dumb_create = i915_gem_dumb_create,
|
||||
.dumb_map_offset = i915_gem_mmap_gtt,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
.ioctls = i915_ioctls,
|
||||
.num_ioctls = ARRAY_SIZE(i915_ioctls),
|
||||
.fops = &i915_driver_fops,
|
||||
|
@ -802,12 +802,10 @@ void intel_crt_reset(struct drm_encoder *encoder)
|
||||
*/
|
||||
|
||||
static const struct drm_connector_funcs intel_crt_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.destroy = intel_crt_destroy,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
};
|
||||
|
@ -13323,7 +13323,6 @@ static int intel_atomic_commit(struct drm_device *dev,
|
||||
static const struct drm_crtc_funcs intel_crtc_funcs = {
|
||||
.gamma_set = drm_atomic_helper_legacy_gamma_set,
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.set_property = drm_atomic_helper_crtc_set_property,
|
||||
.destroy = intel_crtc_destroy,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.atomic_duplicate_state = intel_crtc_duplicate_state,
|
||||
@ -13600,7 +13599,6 @@ const struct drm_plane_funcs intel_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = intel_plane_destroy,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.atomic_get_property = intel_plane_atomic_get_property,
|
||||
.atomic_set_property = intel_plane_atomic_set_property,
|
||||
.atomic_duplicate_state = intel_plane_duplicate_state,
|
||||
@ -13735,7 +13733,6 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
|
||||
.update_plane = intel_legacy_cursor_update,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = intel_plane_destroy,
|
||||
.set_property = drm_atomic_helper_plane_set_property,
|
||||
.atomic_get_property = intel_plane_atomic_get_property,
|
||||
.atomic_set_property = intel_plane_atomic_set_property,
|
||||
.atomic_duplicate_state = intel_plane_duplicate_state,
|
||||
@ -13809,18 +13806,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
|
||||
0, &intel_plane_funcs,
|
||||
intel_primary_formats, num_formats,
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
"plane 1%c", pipe_name(pipe));
|
||||
else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
|
||||
0, &intel_plane_funcs,
|
||||
intel_primary_formats, num_formats,
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
"primary %c", pipe_name(pipe));
|
||||
else
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
|
||||
0, &intel_plane_funcs,
|
||||
intel_primary_formats, num_formats,
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
"plane %c", plane_name(primary->plane));
|
||||
if (ret)
|
||||
@ -13906,7 +13906,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
||||
0, &intel_cursor_plane_funcs,
|
||||
intel_cursor_formats,
|
||||
ARRAY_SIZE(intel_cursor_formats),
|
||||
DRM_PLANE_TYPE_CURSOR,
|
||||
NULL, DRM_PLANE_TYPE_CURSOR,
|
||||
"cursor %c", pipe_name(pipe));
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
@ -5007,10 +5007,8 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dp_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.force = intel_dp_force,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.late_register = intel_dp_connector_register,
|
||||
|
@ -346,10 +346,8 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dp_mst_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.destroy = intel_dp_mst_connector_destroy,
|
||||
|
@ -786,7 +786,6 @@ struct intel_crtc {
|
||||
struct drm_crtc base;
|
||||
enum pipe pipe;
|
||||
enum plane plane;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
/*
|
||||
* Whether the crtc and the connected output pipeline is active. Implies
|
||||
* that crtc->enabled is set, i.e. the current mode configuration has
|
||||
|
@ -1653,12 +1653,10 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_dsi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.destroy = intel_dsi_connector_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
|
@ -344,13 +344,11 @@ static void intel_dvo_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dvo_detect,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.destroy = intel_dvo_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
};
|
||||
|
@ -280,27 +280,6 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Sets the color ramps on behalf of RandR */
|
||||
static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
|
||||
intel_crtc->lut_r[regno] = red >> 8;
|
||||
intel_crtc->lut_g[regno] = green >> 8;
|
||||
intel_crtc->lut_b[regno] = blue >> 8;
|
||||
}
|
||||
|
||||
static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, int regno)
|
||||
{
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
|
||||
*red = intel_crtc->lut_r[regno] << 8;
|
||||
*green = intel_crtc->lut_g[regno] << 8;
|
||||
*blue = intel_crtc->lut_b[regno] << 8;
|
||||
}
|
||||
|
||||
static struct drm_fb_helper_crtc *
|
||||
intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
|
||||
{
|
||||
@ -375,7 +354,6 @@ retry:
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_fb_helper_crtc *new_crtc;
|
||||
struct intel_crtc *intel_crtc;
|
||||
|
||||
fb_conn = fb_helper->connector_info[i];
|
||||
connector = fb_conn->connector;
|
||||
@ -417,13 +395,6 @@ retry:
|
||||
|
||||
num_connectors_enabled++;
|
||||
|
||||
intel_crtc = to_intel_crtc(connector->state->crtc);
|
||||
for (j = 0; j < 256; j++) {
|
||||
intel_crtc->lut_r[j] = j;
|
||||
intel_crtc->lut_g[j] = j;
|
||||
intel_crtc->lut_b[j] = j;
|
||||
}
|
||||
|
||||
new_crtc = intel_fb_helper_crtc(fb_helper,
|
||||
connector->state->crtc);
|
||||
|
||||
@ -526,8 +497,6 @@ bail:
|
||||
|
||||
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
||||
.initial_config = intel_fb_initial_config,
|
||||
.gamma_set = intel_crtc_fb_gamma_set,
|
||||
.gamma_get = intel_crtc_fb_gamma_get,
|
||||
.fb_probe = intelfb_create,
|
||||
};
|
||||
|
||||
|
@ -1706,11 +1706,9 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_hdmi_detect,
|
||||
.force = intel_hdmi_force,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.late_register = intel_connector_register,
|
||||
|
@ -595,10 +595,8 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_lvds_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.late_register = intel_connector_register,
|
||||
|
@ -2193,10 +2193,8 @@ intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_sdvo_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.atomic_get_property = intel_sdvo_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_sdvo_connector_atomic_set_property,
|
||||
.late_register = intel_sdvo_connector_register,
|
||||
|
@ -1171,13 +1171,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
|
||||
possible_crtcs, &intel_plane_funcs,
|
||||
plane_formats, num_plane_formats,
|
||||
DRM_PLANE_TYPE_OVERLAY,
|
||||
NULL, DRM_PLANE_TYPE_OVERLAY,
|
||||
"plane %d%c", plane + 2, pipe_name(pipe));
|
||||
else
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
|
||||
possible_crtcs, &intel_plane_funcs,
|
||||
plane_formats, num_plane_formats,
|
||||
DRM_PLANE_TYPE_OVERLAY,
|
||||
NULL, DRM_PLANE_TYPE_OVERLAY,
|
||||
"sprite %c", sprite_name(pipe, plane));
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
@ -1407,11 +1407,9 @@ intel_tv_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_tv_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.destroy = intel_tv_destroy,
|
||||
.set_property = drm_atomic_helper_connector_set_property,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
|
@ -182,8 +182,6 @@ static struct drm_driver imx_drm_driver = {
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
|
@ -389,7 +389,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
|
||||
|
||||
static const struct drm_connector_funcs imx_ldb_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = imx_drm_connector_destroy,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -341,7 +341,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs imx_tve_connector_funcs = {
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = imx_drm_connector_destroy,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
|
@ -718,8 +718,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
|
||||
|
||||
ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
|
||||
&ipu_plane_funcs, ipu_plane_formats,
|
||||
ARRAY_SIZE(ipu_plane_formats), type,
|
||||
NULL);
|
||||
ARRAY_SIZE(ipu_plane_formats),
|
||||
NULL, type, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to initialize plane\n");
|
||||
kfree(ipu_plane);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user