linux/drivers/gpu/drm/nouveau/dispnv50/disp.c

/*
 * Copyright 2011 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 */
#include "disp.h"
#include "atom.h"
#include "core.h"
#include "head.h"
#include "wndw.h"
#include "handles.h"

#include <linux/backlight.h>
#include <linux/dma-mapping.h>
#include <linux/hdmi.h>
#include <linux/component.h>
#include <linux/iopoll.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_scdc_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fixed.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>

#include <nvif/push507c.h>

#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/event.h>
#include <nvif/if0012.h>
#include <nvif/if0014.h>
#include <nvif/timer.h>

#include <nvhw/class/cl507c.h>
#include <nvhw/class/cl507d.h>
#include <nvhw/class/cl837d.h>
#include <nvhw/class/cl887d.h>
#include <nvhw/class/cl907d.h>
#include <nvhw/class/cl917d.h>

#include "nouveau_drv.h"
#include "nouveau_dma.h"
#include "nouveau_gem.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_fence.h"
#include "nv50_display.h"

/******************************************************************************
 * EVO channel
 *****************************************************************************/

static int
nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
		 const s32 *oclass, u8 head, void *data, u32 size,
		 struct nv50_chan *chan)
{}

static void
nv50_chan_destroy(struct nv50_chan *chan)
{}

/******************************************************************************
 * DMA EVO channel
 *****************************************************************************/

void
nv50_dmac_destroy(struct nv50_dmac *dmac)
{}

static void
nv50_dmac_kick(struct nvif_push *push)
{}

static int
nv50_dmac_free(struct nv50_dmac *dmac)
{}

static int
nv50_dmac_wind(struct nv50_dmac *dmac)
{}

static int
nv50_dmac_wait(struct nvif_push *push, u32 size)
{}

MODULE_PARM_DESC();
static int nv50_dmac_vram_pushbuf =;
module_param_named(kms_vram_pushbuf, nv50_dmac_vram_pushbuf, int, 0400);

int
nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
		 const s32 *oclass, u8 head, void *data, u32 size, s64 syncbuf,
		 struct nv50_dmac *dmac)
{}

/******************************************************************************
 * Output path helpers
 *****************************************************************************/
static void
nv50_outp_dump_caps(struct nouveau_drm *drm,
		    struct nouveau_encoder *outp)
{}

static int
nv50_outp_atomic_check_view(struct drm_encoder *encoder,
			    struct drm_crtc_state *crtc_state,
			    struct drm_connector_state *conn_state,
			    struct drm_display_mode *native_mode)
{}

static void
nv50_outp_atomic_fix_depth(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state)
{}

static int
nv50_outp_atomic_check(struct drm_encoder *encoder,
		       struct drm_crtc_state *crtc_state,
		       struct drm_connector_state *conn_state)
{}

struct nouveau_connector *
nv50_outp_get_new_connector(struct drm_atomic_state *state, struct nouveau_encoder *outp)
{}

struct nouveau_connector *
nv50_outp_get_old_connector(struct drm_atomic_state *state, struct nouveau_encoder *outp)
{}

static struct nouveau_crtc *
nv50_outp_get_new_crtc(const struct drm_atomic_state *state, const struct nouveau_encoder *outp)
{}

/******************************************************************************
 * DAC
 *****************************************************************************/
static void
nv50_dac_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static void
nv50_dac_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static enum drm_connector_status
nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{}

static const struct drm_encoder_helper_funcs
nv50_dac_help =;

static void
nv50_dac_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs
nv50_dac_func =;

static int
nv50_dac_create(struct nouveau_encoder *nv_encoder)
{}

/*
 * audio component binding for ELD notification
 */
static void
nv50_audio_component_eld_notify(struct drm_audio_component *acomp, int port,
				int dev_id)
{}

static int
nv50_audio_component_get_eld(struct device *kdev, int port, int dev_id,
			     bool *enabled, unsigned char *buf, int max_bytes)
{}

static const struct drm_audio_component_ops nv50_audio_component_ops =;

static int
nv50_audio_component_bind(struct device *kdev, struct device *hda_kdev,
			  void *data)
{}

static void
nv50_audio_component_unbind(struct device *kdev, struct device *hda_kdev,
			    void *data)
{}

static const struct component_ops nv50_audio_component_bind_ops =;

static void
nv50_audio_component_init(struct nouveau_drm *drm)
{}

static void
nv50_audio_component_fini(struct nouveau_drm *drm)
{}

/******************************************************************************
 * Audio
 *****************************************************************************/
static bool
nv50_audio_supported(struct drm_encoder *encoder)
{}

static void
nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
{}

static void
nv50_audio_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc,
		  struct nouveau_connector *nv_connector, struct drm_atomic_state *state,
		  struct drm_display_mode *mode)
{}

/******************************************************************************
 * HDMI
 *****************************************************************************/
static void
nv50_hdmi_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc,
		 struct nouveau_connector *nv_connector, struct drm_atomic_state *state,
		 struct drm_display_mode *mode, bool hda)
{}

/******************************************************************************
 * MST
 *****************************************************************************/
#define nv50_mstm(p)
#define nv50_mstc(p)
#define nv50_msto(p)

struct nv50_mstc {};

struct nv50_msto {};

struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder)
{}

static void
nv50_msto_cleanup(struct drm_atomic_state *state,
		  struct drm_dp_mst_topology_state *new_mst_state,
		  struct drm_dp_mst_topology_mgr *mgr,
		  struct nv50_msto *msto)
{}

static void
nv50_msto_prepare(struct drm_atomic_state *state,
		  struct drm_dp_mst_topology_state *mst_state,
		  struct drm_dp_mst_topology_mgr *mgr,
		  struct nv50_msto *msto)
{}

static int
nv50_msto_atomic_check(struct drm_encoder *encoder,
		       struct drm_crtc_state *crtc_state,
		       struct drm_connector_state *conn_state)
{}

static u8
nv50_dp_bpc_to_depth(unsigned int bpc)
{}

static void
nv50_msto_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static void
nv50_msto_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static const struct drm_encoder_helper_funcs
nv50_msto_help =;

static void
nv50_msto_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs
nv50_msto =;

static struct nv50_msto *
nv50_msto_new(struct drm_device *dev, struct nv50_head *head, int id)
{}

static struct drm_encoder *
nv50_mstc_atomic_best_encoder(struct drm_connector *connector,
			      struct drm_atomic_state *state)
{}

static enum drm_mode_status
nv50_mstc_mode_valid(struct drm_connector *connector,
		     struct drm_display_mode *mode)
{}

static int
nv50_mstc_get_modes(struct drm_connector *connector)
{}

static int
nv50_mstc_atomic_check(struct drm_connector *connector,
		       struct drm_atomic_state *state)
{}

static int
nv50_mstc_detect(struct drm_connector *connector,
		 struct drm_modeset_acquire_ctx *ctx, bool force)
{}

static const struct drm_connector_helper_funcs
nv50_mstc_help =;

static void
nv50_mstc_destroy(struct drm_connector *connector)
{}

static const struct drm_connector_funcs
nv50_mstc =;

static int
nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
	      const char *path, struct nv50_mstc **pmstc)
{}

static void
nv50_mstm_cleanup(struct drm_atomic_state *state,
		  struct drm_dp_mst_topology_state *mst_state,
		  struct nv50_mstm *mstm)
{}

static void
nv50_mstm_prepare(struct drm_atomic_state *state,
		  struct drm_dp_mst_topology_state *mst_state,
		  struct nv50_mstm *mstm)
{}

static struct drm_connector *
nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
			struct drm_dp_mst_port *port, const char *path)
{}

static const struct drm_dp_mst_topology_cbs
nv50_mstm =;

bool
nv50_mstm_service(struct nouveau_drm *drm,
		  struct nouveau_connector *nv_connector,
		  struct nv50_mstm *mstm)
{}

void
nv50_mstm_remove(struct nv50_mstm *mstm)
{}

int
nv50_mstm_detect(struct nouveau_encoder *outp)
{}

static void
nv50_mstm_fini(struct nouveau_encoder *outp)
{}

static void
nv50_mstm_init(struct nouveau_encoder *outp, bool runtime)
{}

static void
nv50_mstm_del(struct nv50_mstm **pmstm)
{}

static int
nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
	      int conn_base_id, struct nv50_mstm **pmstm)
{}

/******************************************************************************
 * SOR
 *****************************************************************************/
static void
nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head,
		struct nv50_head_atom *asyh, u8 proto, u8 depth)
{}

/* TODO: Should we extend this to PWM-only backlights?
 * As well, should we add a DRM helper for waiting for the backlight to acknowledge
 * the panel backlight has been shut off? Intel doesn't seem to do this, and uses a
 * fixed time delay from the vbios…
 */
static void
nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

// common/inc/displayport/displayport.h
#define DP_CONFIG_WATERMARK_ADJUST
#define DP_CONFIG_WATERMARK_LIMIT
#define DP_CONFIG_INCREASED_WATERMARK_ADJUST
#define DP_CONFIG_INCREASED_WATERMARK_LIMIT

static bool
nv50_sor_dp_watermark_sst(struct nouveau_encoder *outp,
			  struct nv50_head *head, struct nv50_head_atom *asyh)
{}

static void
nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static const struct drm_encoder_helper_funcs
nv50_sor_help =;

static void
nv50_sor_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs
nv50_sor_func =;

static int
nv50_sor_create(struct nouveau_encoder *nv_encoder)
{}

/******************************************************************************
 * PIOR
 *****************************************************************************/
static int
nv50_pior_atomic_check(struct drm_encoder *encoder,
		       struct drm_crtc_state *crtc_state,
		       struct drm_connector_state *conn_state)
{}

static void
nv50_pior_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static void
nv50_pior_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state)
{}

static const struct drm_encoder_helper_funcs
nv50_pior_help =;

static void
nv50_pior_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs
nv50_pior_func =;

static int
nv50_pior_create(struct nouveau_encoder *nv_encoder)
{}

/******************************************************************************
 * Atomic
 *****************************************************************************/

static void
nv50_disp_atomic_commit_core(struct drm_atomic_state *state, u32 *interlock)
{}

static void
nv50_disp_atomic_commit_wndw(struct drm_atomic_state *state, u32 *interlock)
{}

static void
nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
{}

static void
nv50_disp_atomic_commit_work(struct work_struct *work)
{}

static int
nv50_disp_atomic_commit(struct drm_device *dev,
			struct drm_atomic_state *state, bool nonblock)
{}

static struct nv50_outp_atom *
nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder)
{}

static int
nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
				struct drm_connector_state *old_connector_state)
{}

static int
nv50_disp_outp_atomic_check_set(struct nv50_atom *atom,
				struct drm_connector_state *connector_state)
{}

static int
nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
{}

static void
nv50_disp_atomic_state_clear(struct drm_atomic_state *state)
{}

static void
nv50_disp_atomic_state_free(struct drm_atomic_state *state)
{}

static struct drm_atomic_state *
nv50_disp_atomic_state_alloc(struct drm_device *dev)
{}

static const struct drm_mode_config_funcs
nv50_disp_func =;

static const struct drm_mode_config_helper_funcs
nv50_disp_helper_func =;

/******************************************************************************
 * Init
 *****************************************************************************/

static void
nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend)
{}

static inline void
nv50_display_read_hw_or_state(struct drm_device *dev, struct nv50_disp *disp,
			      struct nouveau_encoder *outp)
{}

/* Read back the currently programmed display state */
static void
nv50_display_read_hw_state(struct nouveau_drm *drm)
{}

static int
nv50_display_init(struct drm_device *dev, bool resume, bool runtime)
{}

static void
nv50_display_destroy(struct drm_device *dev)
{}

int
nv50_display_create(struct drm_device *dev)
{}

/******************************************************************************
 * Format modifiers
 *****************************************************************************/

/****************************************************************
 *            Log2(block height) ----------------------------+  *
 *            Page Kind ----------------------------------+  |  *
 *            Gob Height/Page Kind Generation ------+     |  |  *
 *                          Sector layout -------+  |     |  |  *
 *                          Compression ------+  |  |     |  |  */
const u64 disp50xx_modifiers[] =;

/****************************************************************
 *            Log2(block height) ----------------------------+  *
 *            Page Kind ----------------------------------+  |  *
 *            Gob Height/Page Kind Generation ------+     |  |  *
 *                          Sector layout -------+  |     |  |  *
 *                          Compression ------+  |  |     |  |  */
const u64 disp90xx_modifiers[] =;